Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/120.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为FCM检索令牌的正确方法-iOS 10 Swift 3_Ios_Swift_Firebase_Firebase Cloud Messaging - Fatal编程技术网

为FCM检索令牌的正确方法-iOS 10 Swift 3

为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

我用FirebaseAuth/FCM等实现了Firebase,并通过Firebase控制台成功发送了通知

但是,我需要从我自己的应用服务器推送通知

我想知道以下哪种方法是检索设备注册id的正确方法:-

1)从DidRegisterForRemotionTificationwithDeviceToken检索注册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)

}
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);
       }];