ios设备上的Firebase InstanceID令牌刷新延迟
Posted
技术标签:
【中文标题】ios设备上的Firebase InstanceID令牌刷新延迟【英文标题】:Firebase InstanceID Token Refresh delay on ios device 【发布时间】:2016-10-13 12:51:07 【问题描述】:我已经在我的 ios 应用程序中实现了 Firebase 云消息传递。一切似乎都运行良好,除了一件事,即从应用启动到在 Firebase 中刷新设备令牌需要将近 10 秒的时间。
我已将此代码添加到 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)
为什么InstanceID为(null)时会调用tokenRefreshCallback:
?
为什么要花将近 10 秒才能检索到实际令牌?
【问题讨论】:
【参考方案1】:就我而言。使用深度链接在屏幕之间导航时遇到了同样的问题。
如果没有,一切都很好。
这对我有用。在应用程序 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]];
【讨论】:
以上是关于ios设备上的Firebase InstanceID令牌刷新延迟的主要内容,如果未能解决你的问题,请参考以下文章