3
votes

Integrate Firebase cloud messaging in my application. Successfully install pod and get all the framework. I want to get the refreshedToken for my device and send the notification and receive in my device, and want to track all the button click in my app.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) {
        // iOS 7.1 or earlier
        UIRemoteNotificationType allNotificationTypes =
        (UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge);
        [application registerForRemoteNotificationTypes:allNotificationTypes];
    } else {
        // iOS 8 or later
        // [END_EXCLUDE]
        UIUserNotificationType allNotificationTypes =
        (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
        UIUserNotificationSettings *settings =
        [UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }

    // [START configure_firebase]
    [FIRApp configure];
    // [END configure_firebase]

    // Add observer for InstanceID token refresh callback.
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(tokenRefreshNotification:)
                                                 name:kFIRInstanceIDTokenRefreshNotification object:nil];

    return YES;
}


- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    // If you are receiving a notification message while your app is in the background,
    // this callback will not be fired till the user taps on the notification launching the application.
    // TODO: Handle data of notification

    // Print message ID.
    NSLog(@"Message ID: %@", userInfo[@"gcm.message_id"]);

    // Pring full message.
    NSLog(@"%@", userInfo);
}

- (void)connectToFcm {
    [[FIRMessaging messaging] connectWithCompletion:^(NSError * _Nullable error) {
        if (error != nil) {
            NSLog(@"Unable to connect to FCM. %@", error);
        } else {
            NSLog(@"Connected to FCM.");
        }
    }];
}



- (void)tokenRefreshNotification:(NSNotification *)notification {
    // Note that this callback will be fired everytime a new token is generated, including the first
    // time. So if you need to retrieve the token as soon as it is available this is where that
    // should be done.
    NSString *refreshedToken = [[FIRInstanceID instanceID] token];
    NSLog(@"InstanceID token: %@", refreshedToken);

    // Connect to FCM since connection may have failed when attempted before having a token.
    [self connectToFcm];

    // TODO: If necessary send token to appliation server.
}

- (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [[FIRMessaging messaging] disconnect];

    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    [self connectToFcm];
}

I'm using this code in app delegate. Got these waring in my code. How can I fix this issues. new for development help me.

WARNING: Firebase Analytics App Delegate Proxy is disabled. To log deep link campaigns manually, call the methods in FIRAnalytics+AppDelegate.h. FCMAPP[496:56073] Configuring the default app. Failed to fetch APNS token Error Domain=com.firebase.iid Code=1001 "(null)" FIRMessaging library version 1.1.0 Firebase Analytics v.3200000 started To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled FIRMessaging registration is not ready with auth credentials FCMAPP[496:56073] Unable to connect to FCM. Error Domain=com.google.fcm Code=501 "(null)"

2

2 Answers

2
votes

Use the following Swift code.

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
{
    if #available(iOS 10.0, *)
    {
        // For iOS 10 display notification (sent via APNS)
        UNUserNotificationCenter.currentNotificationCenter().delegate = self
        UNUserNotificationCenter.currentNotificationCenter().requestAuthorizationWithOptions([.Badge, .Sound, .Alert])          { (granted, error) in
            if granted
            {
                //self.registerCategory()
            }
         }
         // For iOS 10 data message (sent via FCM)
         FIRMessaging.messaging().remoteMessageDelegate = self
    }
    else
    {
        let settings: UIUserNotificationSettings =  UIUserNotificationSettings(forTypes: [.Alert,.Badge,.Sound], categories: nil)
        application.registerUserNotificationSettings(settings)
    }          
    application.registerForRemoteNotifications()        
    //Configuring Firebase
    FIRApp.configure()
    // Add observer for InstanceID token refresh callback.
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.tokenRefreshNotification), name: kFIRInstanceIDTokenRefreshNotification, object: nil)     
     return true
}

//Receive Remote Notification on Background
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void)
{
    FIRMessaging.messaging().appDidReceiveMessage(userInfo)
}

func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData)
{
    FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.Sandbox)
    FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.Prod)
}

func tokenRefreshNotification(notification: NSNotification)
{
    if let refreshedToken = FIRInstanceID.instanceID().token()
    {
        print("InstanceID token: \(refreshedToken)")
    }
    // Connect to FCM since connection may have failed when attempted before having a token.
    connectToFcm()
}

func connectToFcm()
{
    FIRMessaging.messaging().connectWithCompletion { (error) in
        if (error != nil)
        {
            print("Unable to connect with FCM. \(error)")
        }
        else
        {
            print("Connected to FCM.")
        }
    }
}

func applicationDidBecomeActive(application: UIApplication)
{            
    connectToFcm()
}
0
votes

Have you set up the application correctly on the Firebase dashboard?

I have encountered this error before, as the Cloud Messaging settings aren't too obvious on the Firebase console.

  1. Open the Firebase console. Click the cog next to your application name and go on "Project Settings".
  2. Select the cloud messaging tab. You'll need to add your iOS APNS certificates here to successfully send push messages (One for development, one for production).

I was getting this error as I hadn't correctly uploaded my apps certificates.

Update:

Another reason for this error that i've encountered this error is that the Firebase SDK sometimes can't obtain the APNS token from apple itself. To resolve this, i've obtained the token manually:

First register for remote notifications:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

...

  // Register for remote notifications.
[[UIApplication sharedApplication] registerForRemoteNotifications];

}

When the APNS token is returned, manually set it on the Firebase instance:

- (void)application:(UIApplication *)app
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {

NSLog(@"Registered for notification device token: %@", devToken);

[[FIRInstanceID instanceID] setAPNSToken:devToken type:FIRInstanceIDAPNSTokenTypeUnknown];

[self connectToFcm];

const void *devTokenBytes = [devToken bytes];

}

Should then successfully be able to connect to Firebase cloud messaging:

- (void)connectToFcm {

NSLog(@"Connecting to FCM...");

[[FIRMessaging messaging] connectWithCompletion:^(NSError * _Nullable error) {
    if (error != nil) {
        NSLog(@"Unable to connect to FCM. %@", error);
    } else {
        NSLog(@"Connected to FCM.");
    }
}];
}

If you cannot obtain the APNS token this way, there is something wrong with your push notification setup on the apple member center. Have you generated a developer/release APNS certificate and added them to your provision profile?