为 FCM 检索令牌的正确方法 - iOS 10 Swift 3
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40013764/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Correct way to retrieve token for FCM - iOS 10 Swift 3
提问by aznelite89
i had implement Firebase with FirebaseAuth/FCM etc and did sent notification successfully through Firebase Console.
我已经使用 FirebaseAuth/FCM 等实现了 Firebase,并通过 Firebase 控制台成功发送了通知。
However i would need to push the notification from my own app server.
但是我需要从我自己的应用服务器推送通知。
i am wondering below which way is correct way to retrieve the registration id for the device:-
我想知道以下哪种方式是检索设备注册 ID 的正确方法:-
1) retrieve registration id token from didRegisterForRemoteNotificationWithDeviceToken
1) 从 didRegisterForRemoteNotificationWithDeviceToken 中检索注册 id 令牌
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
var token = ""
for i in 0..<deviceToken.count {
token += String(format: "%02.2hhx", arguments: [deviceToken[i]])
}
print("Registration succeeded!")
print("Token: ", token)
Callquery(token)
}
2) Retrieve Registration token from firebase(Based on Firebase document which retrieve the current registration token)
2) 从 firebase 检索注册令牌(基于检索当前注册令牌的 Firebase 文档)
let token = FIRInstanceID.instanceID().token()!
i was using the first way, the push notification is not being received even the registration id is stored on my app server database accordingly and i get this CURL session result :-
我使用的是第一种方式,即使注册 ID 相应地存储在我的应用服务器数据库中,也没有收到推送通知,我得到了这个 CURL 会话结果:-
{"multicast_id":6074293608087656831,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}
i had also tried the second way and get fatal error while running the app as below:-
我也尝试过第二种方式,并在运行应用程序时出现致命错误,如下所示:-
appreciated if anyone could point me the right way, thanks!
如果有人能指出我正确的方法,不胜感激,谢谢!
回答by Sam
The tokenRefreshNotification
function doesn't always get called when launching the app.
tokenRefreshNotification
启动应用程序时并不总是调用该函数。
However, when placing the code inside the regular didRegisterForRemoteNotificationsWithDeviceToken
delegate function, I can get the token every time:
但是,当将代码放在常规didRegisterForRemoteNotificationsWithDeviceToken
委托函数中时,我每次都可以获得令牌:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
if let refreshedToken = InstanceID.instanceID().token() {
print("InstanceID token: \(refreshedToken)")
}
}
(Swift 3 + Firebase 4.0.4)
(Swift 3 + Firebase 4.0.4)
回答by Musa almatri
The recommended way by Firebase:
Firebase 推荐的方式:
let token = Messaging.messaging().fcmToken
Reference : Setting Up a Firebase Cloud Messaging Client App on iOS
回答by MBH
Swift 3 + Firebase 4.0.4 :
Swift 3 + Firebase 4.0.4:
static var FirebaseToken : String? {
return InstanceID.instanceID().token()
}
回答by Daniyal Raza
Swift 4 + Firebase (5.3.0)
Swift 4 + Firebase (5.3.0)
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
InstanceID.instanceID().instanceID(handler: { (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)")
}
})
}
回答by cohen72
Swift 4
斯威夫特 4
Courtesy of: https://stackoverflow.com/a/50945350/1014164
礼貌:https: //stackoverflow.com/a/50945350/1014164
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)")
}
}
回答by jazzbpn
FCM Device Token swift3
FCM 设备令牌 swift3
let fcmDeviceToken = FIRInstanceID.instanceID().token()
print("FCM token: \(fcmDeviceToken ?? "")")
回答by John Leonardo
Go with the second option, and this is going to seem really stupid/simple, but to fix that nil optional fatal error, just remove the force-unwrap at the end
选择第二个选项,这看起来真的很愚蠢/简单,但是要修复 nil 可选的致命错误,只需在最后删除 force-unwrap
Your code:var token = FIRInstanceID.instanceID().token()!
Make it:var token = FIRInstanceID.instanceID().token()
你的代码:var token = FIRInstanceID.instanceID().token()!
让它:var token = FIRInstanceID.instanceID().token()
That will at least fix that nasty crash
这至少会解决那个令人讨厌的崩溃
回答by Naveen Ramanathan
First register for the firebase token refresh notification:
首先注册 firebase 令牌刷新通知:
NotificationCenter.default.addObserver(self, selector:
#selector(tokenRefreshNotification), name:
NSNotification.Name.InstanceIDTokenRefresh, object: nil)
Then you can receive the token in the tokenRefreshNotification selector:
然后你可以在 tokenRefreshNotification 选择器中接收令牌:
func tokenRefreshNotification(_ notification: Notification) {
if let refreshedToken = FIRInstanceID.instanceID().token() {
print("InstanceID token: \(refreshedToken)")
}
// Connect to FCM since connection may have failed when attempted before having a token.
connectToFcm()
}
回答by Brownsoo Han
To Get current FCM Token
获取当前的 FCM 令牌
if let token = Messaging.messaging().fcmToken {
// token is current fcmToken
}
To Renew current FCM Token
更新当前的 FCM 令牌
If we delete current instanceId, new token will be received vi MessagingDelegate (messaging:didReceiveRegistrationToken) a moment later.
如果我们删除当前的 instanceId,稍后将通过 MessagingDelegate (messaging:didReceiveRegistrationToken) 收到新令牌。
InstanceID.instanceID().deleteID { (error) in
if let er = error {
print(er.localizedDescription)
} else {
print("instanceID().deleteID success ---------------?")
}
}
回答by erickva
I was having the same problem, but could not figure out what was going on.
我遇到了同样的问题,但无法弄清楚发生了什么。
The didRegisterForRemoteNotificationsWithDeviceToken
suggested by @Sam is called (almost) every time, so it is a good work around. BUT, it is NOT called the first time you open the app with the refreshed token.
didRegisterForRemoteNotificationsWithDeviceToken
@Sam的建议(几乎)每次都会被调用,因此这是一个很好的解决方法。但是,它不会在您第一次使用刷新的令牌打开应用程序时调用。
So for this scenario you still need the:
因此,对于这种情况,您仍然需要:
func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
print("Refreshed Token: \(fcmToken)")
}
So if you only use the:
所以如果你只使用:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
if let fcmToken = InstanceID.instanceID().token() {
print("InstanceID token: \(fcmToken)")
}
}
You will only get the "refreshed token" the second time the user opens the app.
您只会在用户第二次打开应用程序时获得“刷新令牌”。
I managed to force a refresh token by uninstalling the app and cleaning the Build Folder (Product > Clean Build Folder). Good for testing.
我设法通过卸载应用程序并清理构建文件夹(产品 > 清理构建文件夹)来强制刷新令牌。适合测试。
Ideally it could all be handled at messaging:didReceiveRegistrationToken
delegate method, but I was not able to make it work. Another way to get notified for changes in the FCM token is to listen NSNotification
named kFIRMessagingRegistrationTokenRefreshNotification
as suggested in the documentation: https://firebase.google.com/docs/cloud-messaging/ios/client
理想情况下,它都可以在messaging:didReceiveRegistrationToken
委托方法中处理,但我无法使其工作。得到通知在FCM变化令牌是听另一种方式NSNotification
命名kFIRMessagingRegistrationTokenRefreshNotification
,如文档中建议:https://firebase.google.com/docs/cloud-messaging/ios/client