FireOS InstanceID令牌在ios设备上刷新延迟

时间:2016-10-13 12:51:08

标签: ios objective-c firebase push-notification firebase-cloud-messaging

我已在iOS应用程序中实施Firebase Cloud Messaging。一切似乎都运行得很好,除了一件事,事实上应用程序需要差不多10秒才能启动以在Firebase中刷新设备令牌。

我已将此代码添加到App Delegate中的application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法:

[FIRApp configure];

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

这是tokenRefreshCallback:方法:

- (void)tokenRefreshCallback:(NSNotification *)notification {

    NSString *refreshedToken = [[FIRInstanceID instanceID] token];
    NSLog(@"InstanceID token: %@", refreshedToken);

    if ([[FIRInstanceID instanceID] token] != NULL) {
        [[FIRMessaging messaging] subscribeToTopic:@"/topics/news"];
        NSLog(@"Subscribed to news topic");
    }

    //Connect to FCM since connection may have failed when attempting before having a token
    [self connectToFirebase];

}

这是记录器的相关部分:

2016-10-13 14:36:23.844 My-App[1111] <Debug> [Firebase/Core][I-COR000001] Configuring the default app.
2016-10-13 14:36:26.492 My-App[1111:2222222] InstanceID token: (null)
2016-10-13 14:36:32.732 My-App[1111:2222222] InstanceID token: c1kmaskdmj...(the actual device token)
  1. 为什么在InstanceID为(null)时调用tokenRefreshCallback:

  2. 为什么在检索实际令牌之前需要大约10秒钟?

1 个答案:

答案 0 :(得分:2)

就我而言。使用深层链接在屏幕之间导航时遇到了同样的问题。

如果没有这一切都很好。

这对我有用。在应用程序didFinishLaunchingWithOptions中,我调用[self configureFirebase];

- (void)configureFirebase {
    [FIRApp configure];
    if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) {
        UIUserNotificationType allNotificationTypes =
        (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
        UIUserNotificationSettings *settings =
        [UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
    } else {
        // iOS 10 or later
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
        UNAuthorizationOptions authOptions =
        UNAuthorizationOptionAlert
        | UNAuthorizationOptionSound
        | UNAuthorizationOptionBadge;
        [[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:authOptions completionHandler:^(BOOL granted, NSError * _Nullable error) {
        }];

        // For iOS 10 display notification (sent via APNS)
        [UNUserNotificationCenter currentNotificationCenter].delegate = self;
        // For iOS 10 data message (sent via FCM)
        [FIRMessaging messaging].remoteMessageDelegate = self;
#endif
    }

    [[UIApplication sharedApplication] registerForRemoteNotifications];
}

我也实现了这个消息:

// [START receive_message]
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    if (!(application.applicationState == UIApplicationStateActive)) {
        [AuthenticationController showAuthenticationViews:self.window];
    }
    [self readNotification:userInfo];
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    [self readNotification:userInfo];
    completionHandler(UIBackgroundFetchResultNewData);
}
// [END receive_message]

// [START ios_10_message_handling]
// Receive displayed notifications for iOS 10 devices.
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
// Handle incoming notification messages while app is in the foreground.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
    NSDictionary *userInfo = notification.request.content.userInfo;
    [self readNotification:userInfo];
    completionHandler(UNNotificationPresentationOptionNone);
}

// Handle notification messages after display notification is tapped by the user.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
    NSDictionary *userInfo = response.notification.request.content.userInfo;
    [self readNotification:userInfo];
    completionHandler();
}
#endif
// [END ios_10_message_handling]

// [START ios_10_data_message_handling]
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
// Receive data message on iOS 10 devices while app is in the foreground.
- (void)applicationReceivedRemoteMessage:(FIRMessagingRemoteMessage *)remoteMessage {
    // Print full message
    //NSLog(@"%@", remoteMessage.appData);
}
#endif
// [END ios_10_data_message_handling]

// [START refresh_token]
- (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 application server.
}
// [END refresh_token]

// [START connect_to_fcm]
- (void)connectToFcm {
    // Won't connect since there is no token
    if (![[FIRInstanceID instanceID] token]) {
        return;
    }

    // Disconnect previous FCM connection if it exists.
    [[FIRMessaging messaging] disconnect];
    [[FIRMessaging messaging] connectWithCompletion:^(NSError * _Nullable error) {
        if (error != nil) {
            // NSLog(@"Unable to connect to FCM. %@", error);
        } else {
            [[FIRMessaging messaging] subscribeToTopic:notificationTopic];
            //NSLog(@"Connected to FCM.");
        }
    }];
}
// [END connect_to_fcm]

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    //  NSLog(@"Unable to register for remote notifications: %@", error);
}

// This function is added here only for debugging purposes, and can be removed if swizzling is enabled.
// If swizzling is disabled then this function must be implemented so that the APNs token can be paired to
// the InstanceID token.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    // NSLog(@"APNs token retrieved: %@", deviceToken);

    // With swizzling disabled you must set the APNs token here.
    // [[FIRInstanceID instanceID] setAPNSToken:deviceToken type:FIRInstanceIDAPNSTokenTypeSandbox];
    BOOL automatic = [[[NSUserDefaults standardUserDefaults] objectForKey:@"automaticLogin"] boolValue];
    if (!automatic) {
        [[NSUserDefaults standardUserDefaults] setObject:@(YES) forKey:@"automaticLogin"];
        [self moveToInit];
    }
}

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

// [START disconnect_from_fcm]
- (void)applicationDidEnterBackground:(UIApplication *)application {
    [[FIRMessaging messaging] disconnect];
    // NSLog(@"Disconnected from FCM");
}
// [END disconnect_from_fcm]

#pragma mark - Process notifications



- (void)readNotification:(NSDictionary *)userInfo {
   //read your notification
}

-(void)readLaunchWithOptions:(NSDictionary*)launchOptions{
    if (launchOptions[notificationKey]) {
        [self readNotification:launchOptions[notificationKey]];
    }
}