ios - 如何检测真正的 iOS/APNS 推送令牌何时向 Firebase Cloud Messaging (FCM) 注册?
问题描述
didReceiveRegistrationToken
即使用户没有授予推送通知权限,如下所示的Firebase也会被调用。我需要确保正在注册 APNS 推送令牌以进行分析,并将其保存在我的服务器上,但即使用户未授予推送权限,也会调用此函数。♂️</p>
/**
* Requirement for Firebase push notifications.
* See documentation here: https://firebase.google.com/docs/cloud-messaging/ios/client
*/
extension AppDelegate: MessagingDelegate {
// Note: This callback is fired at each app startup and whenever a new token is generated.
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
print("Firebase registration token: \(fcmToken)")
let dataDict: [String: String] = ["token": fcmToken]
NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
print("Getting called even if the user hasn't opted in for push notifications!")
}
}
解决方案
TL;DR:FCM 令牌不是检测 APNS 令牌是否已注册的可靠方法。在 firebase 中禁用方法 swizzling 并手动收听 APNS 注册。
FCM Tokens: FCM 令牌也称为设备实例 ID;它标识该特定设备上的特定应用程序。换句话说,FCM 令牌不等于 APNS 令牌。这是一种解释:APNs、FCM 或 GCM 令牌。
FCM 令牌自动生成:令人惊讶的是,即使没有 iOS 用户授予权限,Firebase 也会在应用启动时生成 FCM 令牌。我猜它想找到一种方法来识别应用程序和设备对,所以一旦你启动,你就会有一个 FCM 令牌。如果需要,您可以禁用自动生成并等待用户选择加入。
默认情况下,FCM SDK 在应用启动时为客户端应用实例生成一个注册令牌。如果您想在使用实例 ID 之前获得明确的选择加入,您可以通过禁用 FCM 来防止在配置时生成。为此,请将元数据值添加到您的 Info.plist(而不是您的 GoogleService-Info.plist):
这就是问题之一!即使用户禁用了 FCM 令牌的自动生成,也会在提示用户启用推送通知时生成一个,而不是在用户接受推送通知权限时生成。这似乎很奇怪,我最终向 Firebase 报告了这一点。
- APNS Token Swizzling:因此默认情况下 Firebase 接管 AppDelegate 的didRegisterForRemoteNotificationsWithDeviceToken(称为“swizzling”)。您可以禁用它并自己覆盖委托方法。这将使您可以访问 APNS 令牌和 FCM 令牌。
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
print("Successfully registered for notifications!")
// Required to make FCM work since we disabled swizzling!
Messaging.messaging().apnsToken = deviceToken
// String version of APNS so we can use save it/use it later/do analytics.
let apnsToken = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
}
推荐阅读
- javascript - 用于替换 Kendo Grid 中数据的 Javascript 函数
- android - 用android发送64bit红外信号
- r - 使用 dplyr 和 R 将值转换为基于键表的键
- reporting-services - 来自两个不同数据集的 SSRS 时间线报告
- powershell - 用于删除上次访问或创建的文件的批处理文件,超过 X 天
- c# - 从 Excel 中提取数据
- angular - Angular - 带有一个选项数组的多项选择
- reactjs - 无法使用 Jest/Enzyme 测试面板内的组件
- asp.net - 如何获取令牌的声明身份或从令牌 oauth2
- css - SCSS:如何不在 CSS 文件中重复声明?