我使用FirebaseAuth / FCM等实施了Firebase,并通过Firebase控制台成功发送了通知。
但是我需要从我自己的应用服务器推送通知。
我想知道下面哪种方法是检索设备注册ID的正确方法: -
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)从firebase检索注册令牌(基于检索当前注册令牌的Firebase文档)
let token = FIRInstanceID.instanceID().token()!
我正在使用第一种方式,即使注册ID相应地存储在我的应用服务器数据库上也没有收到推送通知,我得到了这个CURL会话结果: -
{"multicast_id":6074293608087656831,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}
我还尝试了第二种方式,并在运行应用程序时遇到致命错误,如下所示: -
感谢任何人都能指出正确的方式,谢谢!
答案 0 :(得分:49)
启动应用时,并不总是会调用tokenRefreshNotification
函数。
但是,当将代码放在常规didRegisterForRemoteNotificationsWithDeviceToken
委托函数中时,我每次都可以获取令牌:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
if let refreshedToken = InstanceID.instanceID().token() {
print("InstanceID token: \(refreshedToken)")
}
}
(Swift 3 + Firebase 4.0.4)
答案 1 :(得分:23)
static var FirebaseToken : String? {
return InstanceID.instanceID().token()
}
答案 2 :(得分:19)
Firebase推荐的方式:
Context context;
OcrDetectorProcessor(GraphicOverlay<OcrGraphic> ocrGraphicOverlay, Context context) {
mGraphicOverlay = ocrGraphicOverlay;
this.context = context;
}
@Override
public void receiveDetections(Detector.Detections<TextBlock> detections) {
mGraphicOverlay.clear();
final String result;
String detectedText = "";
SparseArray<TextBlock> items = detections.getDetectedItems();
for (int i = 0; i < items.size(); ++i) {
final TextBlock item = items.valueAt(i);
OcrGraphic graphic = new OcrGraphic(mGraphicOverlay, item);
mGraphicOverlay.add(graphic);
detectedText += item.getValue();
}
result = detectedText;
((OcrCaptureActivity)context).runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(context, result, Toast.LENGTH_SHORT).show();
}
});
}
答案 3 :(得分:9)
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)")
}
})
}
答案 4 :(得分:7)
快捷键4
由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)")
}
}
答案 5 :(得分:6)
FCM设备令牌swift3
let fcmDeviceToken = FIRInstanceID.instanceID().token()
print("FCM token: \(fcmDeviceToken ?? "")")
答案 6 :(得分:5)
使用第二个选项,这看起来真的很愚蠢/简单,但要修复那个nil可选的致命错误,只需删除最后的force-unwrap
您的代码:
var token = FIRInstanceID.instanceID().token()!
成功:
var token = FIRInstanceID.instanceID().token()
这至少可以解决这个令人讨厌的崩溃
答案 7 :(得分:5)
首先注册firebase令牌刷新通知:
NotificationCenter.default.addObserver(self, selector:
#selector(tokenRefreshNotification), name:
NSNotification.Name.InstanceIDTokenRefresh, object: nil)
然后您可以在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()
}
答案 8 :(得分:2)
我遇到了同样的问题,但无法弄清楚到底是怎么回事。
@Sam建议的didRegisterForRemoteNotificationsWithDeviceToken
每次都(几乎)被调用,因此这是一个很好的解决方法。但是,第一次使用刷新的令牌打开应用程序时不会调用它。
因此,在这种情况下,您仍然需要:
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)")
}
}
您将仅在用户第二次打开应用程序时获得“刷新令牌”。
我设法通过卸载应用程序并清理构建文件夹(产品>清洁构建文件夹)来强制刷新令牌。很适合测试。
理想情况下,它们都可以在messaging:didReceiveRegistrationToken
委托方法下进行处理,但是我无法使其工作。通知FCM令牌更改的另一种方法是,按照文档https://firebase.google.com/docs/cloud-messaging/ios/client
NSNotification
的{{1}}
答案 9 :(得分:1)
首先导入像:
这样的库import FirebaseInstanceID
import FirebaseMessaging
import UserNotifications
设置代理: MessagingDelegate,UNUserNotificationCenterDelegate
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate, UNUserNotificationCenterDelegate {
在didFinishLaunching()上编写此代码:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
Messaging.messaging().delegate = self
//remote Notifications
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (isGranted, err) in
if err != nil {
//Something bad happend
} else {
UNUserNotificationCenter.current().delegate = self
Messaging.messaging().delegate = self
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
}
} else {
// Fallback on earlier versions
}
if #available(iOS 10, *) {
UNUserNotificationCenter.current().requestAuthorization(options: [.badge,.sound,.alert], completionHandler: { (granted, error) in
application.registerForRemoteNotifications()
})
}else{
let notificationSettings = UIUserNotificationSettings(types: [.badge,.sound,.alert], categories: nil)
UIApplication.shared.registerUserNotificationSettings(notificationSettings)
UIApplication.shared.registerForRemoteNotifications()
}
return true
}
以这种方式编写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)
}
还要编写用于注册和接收推送通知的委托方法:
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)
}
}
100%正常,轻松且经过测试
注意:强> 1)从xcode的功能部分启用推送通知。
2)检查在firebase项目设置上上传的两个p12证书的两倍。
3)设备令牌只能从真实设备而不是模拟器获取。
答案 10 :(得分:1)
获取当前的FCM令牌
if let token = Messaging.messaging().fcmToken {
// token is current fcmToken
}
续订当前的FCM令牌
如果我们删除当前的instanceId,稍后将通过MessagingDelegate(messaging:didReceiveRegistrationToken)接收新令牌。
InstanceID.instanceID().deleteID { (error) in
if let er = error {
print(er.localizedDescription)
} else {
print("instanceID().deleteID success ---------------➤")
}
}
答案 11 :(得分:0)
这个问题很旧,但是如果有人想在Objective C中使用它,还是可以的。
最新Firebase:6.27.0
在iOS Objective 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);
}];
答案 12 :(得分:-4)
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().apnsToken = deviceToken
let deviceTokenString = deviceToken.reduce("") { $0 + String(format: "%02X", $1) }
print("APNs device token: \(deviceTokenString)"
}