我正在使用Firebase Cloud Messaging 将推送消息传递到可能出现的iOS应用。 我的 FCM 设置包含一个 Firebase 项目和多个 Firebase 应用:
FB Project
App1 Android
App1 iOS
App2 Android
App2 iOS
...
现在的问题是,发送到我的一个iOS应用程序的FCM消息最终被另一个iOS应用程序接收(发送到App1 iOS - App2 iOS收到该消息(。
为了调试这个问题,我遵循了这个优秀的调试指南: https://firebase.googleblog.com/2017/01/debugging-firebase-cloud-messaging-on.html
我发现:
- 直接通过 APNS 传递消息工作正常(请参阅第 4 节(
- 通过带有 cURL 的 FCM 传送消息(第 5 节(会将消息发送到随机应用。
然后,我意识到我设备上的两个客户端应用都具有相同的Firebase 设备令牌。因此,Firebase似乎并没有在令牌级别上区分应用程序。
我仍然希望我的所有iOS都会收到该消息,而不是随机消息。
问题 1:这是 Firebase 的预期行为吗?
现在,在实际应用中,我通过注册到不同的渠道来定位不同的应用,并像这样为应用标识符添加前缀:
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[[FIRMessaging messaging] subscribeToTopic:@"/topics/app1-news"]];
}
发送到该通道会产生随机结果,包括:
- 预期接收的消息 (App1(
- 其他应用(例如 App2(收到的消息
- 多个应用(应用1、应用2等(接收的消息 一个应用(应用2
- 、应用2(多次接收的消息
- 根本没有收到消息
问题2:我怎样才能做到这一点?
这不是预期的行为。FCM 令牌存储在具有授权实体(与整个 Firebase 项目相同(和范围(通常为"*"(的钥匙串中。但是,钥匙串根据应用的捆绑标识符存储它们,这应该将它们彼此分开。
健全性检查:您是否为每个iOS应用程序使用不同的GoogleService-Info.plist文件?
另外,您是否使用共享钥匙串访问组?列表顶部的共享钥匙串访问组是否在您的权利中keychain-access-groups
?这可以解释 SDK 如何意外找到其他应用的 FCM 令牌。在钥匙串的文档中:
当您的应用创建钥匙串项目时,如果您未在项目的属性字典中显式指定
kSecAttrAccessGroup
键,钥匙串服务将使用 App 的访问权限组数组的第一组(如上所示排序(作为默认访问组。如果您的 App 具有keychain-access-groups
权利,则"钥匙串服务"将使用其中的第一个权利。否则,它将使用始终存在的应用程序标识符。因此,默认情况下,除非您添加keychain-access-groups
权利,否则应用会创建只有它有权访问的钥匙串项目。
SDK 通过尝试创建小型钥匙串项并查看访问组(keychain-access-groups
列表中的第一个是默认(来确定"默认访问组"。通常,对于钥匙串访问群组,您希望将应用的应用程序标识符作为第一项,后跟任何共享群组。这样,除非另有指定,否则您的钥匙串项将写入单个应用,除非显式存储在共享访问组中。