简体   繁体   English

iOS设备上的Firebase InstanceID令牌刷新延迟

[英]Firebase InstanceID Token Refresh delay on ios device

I have implemented Firebase Cloud Messaging in my iOS application. 我在iOS应用程序中实现了Firebase Cloud Messaging。 Everything seems to work just fine, except one thing, the fact that it takes almost 10 seconds from the app to launch to get the device token refreshed in Firebase. 除了一件事,一切似乎都可以正常工作,事实是从应用程序启动到将要在Firebase中刷新设备令牌大约需要10秒钟。

I have added this code to the application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method in the 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];

And this is the tokenRefreshCallback: method: 这是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];

}

And this is the relevant part of logger: 这是记录器的相关部分:

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. Why is the tokenRefreshCallback: called when the InstanceID is (null)? 为什么在InstanceID为(null)时调用tokenRefreshCallback:

  2. Why does it take almost 10 seconds before an actual token is retrieved? 为什么要花几乎10秒钟才能检索到实际令牌?

In my case. 就我而言。 I had the same problem when using deeplinking to navigate between screens. 使用深层链接在屏幕之间导航时,我遇到了同样的问题。

Without that all was working good. 没有这些,一切都很好。

this was working for me. 这为我工作。 In application didFinishLaunchingWithOptions I call [self configureFirebase]; 在应用程序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];
}

also I implement this messages: 我也实现以下消息:

// [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]];
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM