我已在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)
为什么在InstanceID为(null)时调用tokenRefreshCallback:
?
为什么在检索实际令牌之前需要大约10秒钟?
答案 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]];
}
}