为FCM检索令牌的正确方法-iOS 10 Swift 3
我用FirebaseAuth/FCM等实现了Firebase,并通过Firebase控制台成功发送了通知 但是,我需要从我自己的应用服务器推送通知 我想知道以下哪种方法是检索设备注册id的正确方法:- 1)从DidRegisterForRemotionTificationwithDeviceToken检索注册id令牌为FCM检索令牌的正确方法-iOS 10 Swift 3,ios,swift,firebase,firebase-cloud-messaging,Ios,Swift,Firebase,Firebase Cloud Messaging,我用FirebaseAuth/FCM等实现了Firebase,并通过Firebase控制台成功发送了通知 但是,我需要从我自己的应用服务器推送通知 我想知道以下哪种方法是检索设备注册id的正确方法:- 1)从DidRegisterForRemotionTificationwithDeviceToken检索注册id令牌 func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDevice
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)
}
if let token = Messaging.messaging().fcmToken {
// token is current fcmToken
}
我使用的是第一种方式,推送通知没有收到,即使注册id相应地存储在我的app server数据库中,我得到了以下CURL会话结果:-
{"multicast_id":6074293608087656831,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}
我还尝试了第二种方法,在运行应用程序时出现致命错误,如下所示:-
如果有人能给我指路,我将不胜感激,谢谢 使用第二个选项,这看起来非常愚蠢/简单,但要修复nil可选致命错误,只需在末尾删除强制展开 您的代码:
var-token=FIRInstanceID.instanceID().token()代码>
成功:
var-token=FIRInstanceID.instanceID().token()
这将至少修复严重的崩溃第一次注册firebase令牌刷新通知:
NotificationCenter.default.addObserver(self, selector:
#selector(tokenRefreshNotification), name:
NSNotification.Name.InstanceIDTokenRefresh, object: nil)
func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
print("\n\n\n\n\n ==== FCM Token: ",fcmToken)
HelperFunction.helper.storeInUserDefaultForKey(name: kFCMToken, val: fcmToken)
ConnectToFCM()
}
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
// UIApplication.shared.applicationIconBadgeNumber += 1
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "Barker"), object: nil)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
print(userInfo)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
print(userInfo)
completionHandler(UIBackgroundFetchResult.newData)
}
}
然后,您可以在令牌刷新通知选择器中接收令牌:
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()
}
启动应用程序时,tokenRefreshNotification
函数并不总是被调用
但是,当将代码放入常规的didRegisterForRemotionTificationswithDeviceToken
委托函数时,我每次都可以获得令牌:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
if let refreshedToken = InstanceID.instanceID().token() {
print("InstanceID token: \(refreshedToken)")
}
}
(Swift 3+Firebase 4.0.4)FCM设备令牌Swift 3
let fcmDeviceToken = FIRInstanceID.instanceID().token()
print("FCM token: \(fcmDeviceToken ?? "")")
Swift 3+Firebase 4.0.4:
Firebase推荐的方法:
let token = Messaging.messaging().fcmToken
参考:首先导入库,如:
import FirebaseInstanceID
import FirebaseMessaging
import UserNotifications
设置委托:MessagingDelegate,UnuseNotificationCenterDelegate
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate, UNUserNotificationCenterDelegate {
在didFinishLaunching()上编写以下代码:
按如下方式编写connectFCM方法:
func ConnectToFCM() {
Messaging.messaging().shouldEstablishDirectChannel = true
if let token = InstanceID.instanceID().token() {
print("\n\n\n\n\n\n\n\n\n\n ====== TOKEN DCS: " + token)
}
还要编写用于注册和接收推送通知的委托方法:
NotificationCenter.default.addObserver(self, selector:
#selector(tokenRefreshNotification), name:
NSNotification.Name.InstanceIDTokenRefresh, object: nil)
func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
print("\n\n\n\n\n ==== FCM Token: ",fcmToken)
HelperFunction.helper.storeInUserDefaultForKey(name: kFCMToken, val: fcmToken)
ConnectToFCM()
}
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
// UIApplication.shared.applicationIconBadgeNumber += 1
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "Barker"), object: nil)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
print(userInfo)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
print(userInfo)
completionHandler(UIBackgroundFetchResult.newData)
}
}
现在我们可以从firebase控制台进行测试。
100%工作、简单且经过测试
注意:
1) 从xcode的功能部分启用推送通知
2) 检查两次firebase项目设置上上载的p12证书
3) 设备令牌只能从真实设备而不是模拟器获取。Swift 4
承蒙:
Swift 4+火力基地(5.3.0)
获取当前FCM令牌
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)
}
if let token = Messaging.messaging().fcmToken {
// token is current fcmToken
}
更新当前FCM令牌
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)
}
if let token = Messaging.messaging().fcmToken {
// token is current fcmToken
}
如果我们删除当前instanceId,那么稍后将收到新的令牌vi MessagingDelegate(消息:didReceiveRegistrationToken)
InstanceID.instanceID().deleteID { (error) in
if let er = error {
print(er.localizedDescription)
} else {
print("instanceID().deleteID success ---------------➤")
}
}
我也有同样的问题,但我不知道发生了什么
@Sam建议的didRegisterForRemotionTificationsWithDeviceToken
几乎每次都会被调用,因此这是一个很好的解决方法。但是,第一次使用刷新的令牌打开应用程序时不会调用它
因此,在这种情况下,您仍然需要:
func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
print("Refreshed Token: \(fcmToken)")
}
因此,如果您仅使用:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
if let fcmToken = InstanceID.instanceID().token() {
print("InstanceID token: \(fcmToken)")
}
}
您将仅在用户第二次打开应用程序时获得“刷新令牌”
我通过卸载应用程序并清理生成文件夹(产品>清理生成文件夹),成功地强制刷新令牌。适合测试
理想情况下,它可以在消息传递:didReceiveRegistrationToken
委托方法中处理,但我无法使它工作。获取FCM令牌更改通知的另一种方法是按照文档中的建议,侦听名为kFIRMessagingRegistrationTokenRefreshNotification的NSNotification
,首先,您应该导入所有必需的LIB
import Firebase
import UserNotifications
稍后在AppDelegate.swift中调用下一个函数
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().apnsToken = deviceToken
InstanceID.instanceID().instanceID { (result, error) in
if let error = error {
print("Error fetching remote instance ID: \(error)")
} else if let result = result {
print("Remote instance ID token: \(result.token)")
}
}
}
确认MessagingDelegate协议
然后您可以添加下面的委托方法并获取Firebase令牌。(文件)
这个问题已经很老了,但如果有人想在目标C中使用它,这个问题仍然存在
最新版本Firebase:6.27.0
在iOS目标C中,我们可以这样使用
[[FIRInstanceID instanceID] instanceIDWithHandler:^(FIRInstanceIDResult * _Nullable result,
NSError * _Nullable error) {
if (error != nil) {
NSLog(@"Error : %@", error);
} else {
token = result.token;
}
NSLog(@"Token %@", result.token);
}];
要获取实例Id,请执行以下操作:
[[FIRInstanceID instanceID] getIDWithHandler:^(NSString *identity, NSError *error) {
if (error != nil) {
NSLog(@"Error : %@", error);
} else {
NSLog(@"instance ID: %@", identity);
}
NSLog(@"IID %@", identity);
}];
您好,John,错误仍然存在,好像FIRInstanceID.instanceID().token()返回了nil。@aznelite89,它为nil的原因是您尚未注册Firebase Cloud Messaging请注意:DidRegisterForremotentificationwithDeviceToken中的deviceToken参数不是Firebase注册令牌。您仍然需要调用return InstanceID.InstanceID().token(),如下所述。这是做什么的?你能解释一下吗?嗨,如何发布请求令牌?如果有人做了我做的事情,deviceToken:Data参数不是FCM注册令牌。InstanceID()中的令牌。令牌()为。我得到的“令牌()”已弃用:请改用instanceIDWithHandler:。对于token(),我改为:InstanceID.InstanceID().InstanceID{(结果,错误)in if error==nil{print(“InstanceID token:(结果)”)}否则{print(错误,“:获取火灾令牌时出错”)}怎么办?注册令牌通过方法消息传递:didReceiveRegistrationToken:
传递。此方法通常在每个应用程序以注册令牌开始时调用一次;您的答案与下面的答案(Messaging.Messaging().fcmToken
)有什么区别@MBHi在主屏幕viewdidload中调用时得到“静态成员'instanceID'不能使用”,你能帮忙吗?@kemdo确保你正在编写instanceID.instanceID().instanceID
和括号,而不是instanceID.instanceID.instanceID
@kemdo,Yocoh,当我得到静态成员的instanceID时,你是如何解决这个问题的。。。。。。问题?请注意,InstancedTokenRefresh
和FIRInstanceID
现在已被弃用。
[[FIRInstanceID instanceID] getIDWithHandler:^(NSString *identity, NSError *error) {
if (error != nil) {
NSLog(@"Error : %@", error);
} else {
NSLog(@"instance ID: %@", identity);
}
NSLog(@"IID %@", identity);
}];