What is the difference between FIRInstanceID.instanceID().token() and Messaging.messaging().fcmToken?
Calling either of them should return the same registration token.
The difference is that FIRInstanceID
only has methods related to the registration token (e.g. getting and deleting the token), while Messaging
(aka FIRMessaging
-- naming changes) in general provides more methods (e.g. subscribing to topics, sending upstream messages).
Correct way to retrieve token for FCM - iOS 10 Swift 3
The tokenRefreshNotification
function doesn't always get called when launching the app.
However, when placing the code inside the regular didRegisterForRemoteNotificationsWithDeviceToken
delegate function, I can get the token every time:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
if let refreshedToken = InstanceID.instanceID().token() {
print("InstanceID token: \(refreshedToken)")
}
}
(Swift 3 + Firebase 4.0.4)
Firebase InstanceID.instanceID().token() method is deprecated
Fetching the current registration token
Registration tokens are delivered via the method
messaging:didReceiveRegistrationToken:
. This method is called generally once per app start with an FCM token. When this method is called, it is the ideal time to:
- If the registration token is new, send it to your application server.
- Subscribe the registration token to topics. This is required only for new subscriptions or for situations where the user has re-installed the app.
You can retrieve the token directly using
instanceIDWithHandler:
. This callback provides anInstanceIDResult
, which contains the token. A non null error is provided if the InstanceID retrieval failed in any way.
You should import FirebaseInstanceID
import FirebaseInstanceID
objective C
on your getTokenMethod
[[FIRInstanceID instanceID] instanceIDWithHandler:^(FIRInstanceIDResult * _Nullable result,
NSError * _Nullable error) {
if (error != nil) {
NSLog(@"Error fetching remote instance ID: %@", error);
} else {
NSLog(@"Remote instance ID token: %@", result.token);
}
}];
Swift
InstanceID.instanceID().instanceID { result, error in
if let error = error {
print("Error fetching remote instange ID: \(error)")
} else if let result = result {
print("Remote instance ID token: \(result.token)")
}
}
Update
InstanceID
is now deprecated. Try
Messaging.messaging().token { token, error in
// Check for error. Otherwise do what you will with token here
}
FirebaseInstanceIdService is deprecated
firebaser here
Check the reference documentation for FirebaseInstanceIdService
:
This class was deprecated.
In favour of overriding
onNewToken
inFirebaseMessagingService
. Once that has been implemented, this service can be safely removed.
Weirdly enough the JavaDoc for FirebaseMessagingService
doesn't mention the onNewToken
method yet. It looks like not all updated documentation has been published yet. I've filed an internal issue to get the updates to the reference docs published, and to get the samples in the guide updated too.
In the meantime both the old/deprecated calls, and the new ones should work. If you're having trouble with either, post the code and I'll have a look.
Swift FIRMessaging push notification token reset
To correctly store the token in your database, you'll need to handle two cases:
- when the app starts
- when the token gets refreshed
First get the current token on app/main view starts by calling FirebaseInstFIRInstanceID.instanceID().token()
in for example viewDidLoad
:
if let token = FIRInstanceID.instanceID().token() {
ref.child("Users").child(id).child(pushToken).updateChildValues(["tokenid":token])
}
Since the current token may not have been generated yet, you need to handle nil
in this code.
Then also monitor for changes to the token by implementing tokenRefreshNotification
:
func tokenRefreshNotification(notification: NSNotification) {
if let refreshedToken = FIRInstanceID.instanceID().token() {
ref.child("Users").child(id).child(pushToken).updateChildValues(["tokenid":refreshedToken])
}
}
Also see this answer I gave to a similar use-case for Android: Update Firebase Instance ID on app update
Firebase Issues iOS 10.3 on Xcode 8.3 Swift 3 FCM notifications not working
You need to add Push notification certificate to FCM Console in Cloud Messaging. Only then It'll be able to send notifications to your App. Also, make sure you've enabled Push notifications in Capabilities in your iOS App.
Update:
extension AppDelegate: MessagingDelegate {
// Registering for Firebase notifications
func configureFirebase(application: UIApplication) {
FirebaseApp.configure()
Messaging.messaging().delegate = self
// Register for remote notifications. This shows a permission dialog on first run, to
// show the dialog at a more appropriate time move this registration accordingly.
// [START register_for_notifications]
if #available(iOS 10.0, *) {
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: {_, _ in })
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
print("-----firebase token: \(String(describing: Messaging.messaging().fcmToken)) ----")
}
//MARK: FCM Token Refreshed
func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
// FCM token updated, update it on Backend Server
}
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
print("remoteMessage: \(remoteMessage)")
}
//Called when a notification is delivered to a foreground app.
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert, .badge, .sound])
}
//Called to let your app know which action was selected by the user for a given notification.
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
print("User Info = \(response.notification.request.content.userInfo)")
completionHandler()
}
}
Call configureFirebase(application:)
inside didFinishLaunchingWithOptions
of your AppDelegate
.
firebase token is null and token refresh is called continously in my testFlight
i have figured it out! just change ANPS Type token from Sandbox to Unknown!
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
// With swizzling disabled you must set the APNs token here.
FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.unknown)
}
Related Topics
Location Access Request in iOS 11
Tableview.Cellforrowatindexpath(Indexpath) Return Nil
How to Retrieve The Name of Participants in Msconversation
Swift 2.0 Replicate Objc_Association_Retain
Sbdata Is Wrong When Sbvalue Comes from a Swift Dictionary
Swift Unable to Locate and Read Property List (.Plist) File
Convenience Failable Initializers Assign Self
Using Index from Foreach in Other Array
Is There a Method to Check The UIcollectionview Item Drag Cancellation If The Item Wasn't Moved
How to Get The Count of a Type Conforming to 'sequence'
Swift Navigation Bar Item Not Calling Action
How to Declare Swift Generic for Enums of Particular Type
How to Use Swipe to Dismiss While Presenting a Fullscreen Modal in iOS 13
How to Access to a Static Cell
Show and Hide Window Instead of Terminating App on Close Click in Cocoa App
Event Scrolling (Scrollviewdidscroll) Never Called - Swift 3