在这个问题上做了大量的研究,首先我的设置是:
我的问题非常简单和直截了当,虽然我似乎无法找到一个明确的方法来解决这个问题。
我部署了我的应用程序的4.2版本。iOS中的()工作得很好。然后,我将4.3部署到TestFlight以开始测试。安装4.3通过TestFlight和FCM停止工作,没有推送通知。如果我删除应用程序,并通过TestFlight推送通知安装4.3再次工作,设备将被注册。
我也可以复制这个问题,更新应用商店最新发布的应用程序的安装版本,这并不奇怪。
我知道InstanceId/device令牌是基于应用程序build+device的,所以当应用程序更新时,令牌更改是有意义的,但是当我从4.2更新到4.3时,令牌是相同的:
const fcmToken = await firebase.messaging().getToken(); //same whether 4.2 or 4.3
是的,firebase.messaging().getToken()在初始创建时被缓存。
所以我很想听听象征性的改变事件:
firebase.messaging().onTokenRefresh(async () => {
console.log('======onTokenRefresh=========');
AsyncStorage.removeItem(FCM_TOKEN_KEY);
await getToken();
});
似乎从未开火。我甚至在我的应用程序中添加了一个按钮,尝试强制使用一个新的InstanceId,并在从TestFlight或AppStore更新版本后向FCM注册,这并没有帮助:
export async function forceRefresh() {
console.log('================force a new registration!!!==========');
AsyncStorage.removeItem(FCM_TOKEN_KEY);
firebase.messaging().deleteToken();
firebase.iid().deleteToken();
registerForPushNotificationsAsync(true);
}
不,不管用。
所以这个故事的寓意是,当我更新我的应用程序的版本,我的客户,谁的推送通知是很好的,将不再注册推送通知,当他们更新他们的应用程序到下一个版本。
可能是我一直在研究的线索:
有趣的是,在应用程序更新开始时,推送通知将停止工作,因为应用程序更新--我看到了两个不同的令牌,也许第一个是苹果APN令牌
2020-01-17 18:48:09.371741-0800 native[4462:1287461] -[RNFirebaseMessaging messaging:didReceiveRegistrationToken:] [Line 86] Received new FCM token: eBBgznWj1FU:APA91bF8vTmpkwcojp4oDSKFzlPDp6ylEIe_WGNzu24SKHS6RR-3xPu2-cX-Qyc8rrMIQMvkCJftT9711ll1WdshBWS4iEpZ3XpiPeTynqM-nvDjpAUUUWJpfT5aeo6G_scDsN9iipwI
2020-01-17 18:48:09.378382-0800 native[4462:1287621] 6.15.0 - [Firebase/InstanceID][I-IID014012] Invalidating cached token for 255558254149 (*) due to token is no longer fresh.
然后再晚一点,在加载push通知工作的应用程序的前一个版本中,我看到了日志中的工作“默认令牌”:
2020-01-17 18:48:09.987571-0800 native[4462:1287610] 6.15.0 - [Firebase/InstanceID][I-IID014001] Token fetch successful, token: dUY5psWDnkv2td1kB_t6Gs:APA91bEaREBt07CWiEyGvP4YAGjxmVQmF0IcXgef5XcvL5KWrHsqcxZZ8L9PqwGzKTPFGy6cdmuVXSvg6kDQjj-652jt5_jbbKMhUFTcam_-FeBp2vGZvBjaBd4aAOtQf1m48htQ8d6B, authorizedEntity: 255558254149, scope:*
2020-01-17 18:48:09.987764-0800 native[4462:1287461] -[RNFirebaseMessaging messaging:didReceiveRegistrationToken:] [Line 86] Received new FCM token: dUY5psWDnkv2td1kB_t6Gs:APA91bEaREBt07CWiEyGvP4YAGjxmVQmF0IcXgef5XcvL5KWrHsqcxZZ8L9PqwGzKTPFGy6cdmuVXSvg6kDQjj-652jt5_jbbKMhUFTcam_-FeBp2vGZvBjaBd4aAOtQf1m48htQ8d6B
2020-01-17 18:48:09.993088-0800 native[4462:1287610] 6.15.0 - [Firebase/InstanceID][I-IID003010] Successfully fetched default token.
2020-01-17 18:48:09.993755-0800 native[4462:1287610] 6.15.0 - [Firebase/InstanceID][I-IID003008] Got default token dUY5psWDnkv2td1kB_t6Gs:APA91bEaREBt07CWiEyGvP4YAGjxmVQmF0IcXgef5XcvL5KWrHsqcxZZ8L9PqwGzKTPFGy6cdmuVXSvg6kDQjj-652jt5_jbbKMhUFTcam_-FeBp2vGZvBjaBd4aAOtQf1m48htQ8d6B
有趣的是,在删除当前版本的应用程序并安装最新版本(在以前的日志中是更新版本)之后,我们可以看到相同的过程相反,首先我的当前令牌被找到,并被认为不再新鲜:
messaging:didReceiveRegistrationToken:] [Line 86] Received new FCM token: dUY5psWDnkv2td1kB_t6Gs:APA91bEaREBt07CWiEyGvP4YAGjxmVQmF0IcXgef5XcvL5KWrHsqcxZZ8L9PqwGzKTPFGy6cdmuVXSvg6kDQjj-652jt5_jbbKMhUFTcam_-FeBp2vGZvBjaBd4aAOtQf1m48htQ8d6B
2020-01-17 19:03:06.651179-0800 native[4475:1291698] 6.15.0 - [Firebase/InstanceID][I-IID014012] Invalidating cached token for 255558254149 (*) due to token is no longer fresh.
随后,新令牌被加载,并被视为默认令牌,我的新安装立即收到FCM通知:
2020-01-17 19:03:07.997209-0800 native[4475:1291564] -[RNFirebaseMessaging messaging:didReceiveRegistrationToken:] [Line 86] Received new FCM token: ebz2ACPpBkg0kGsgs9yF7_:APA91bGErCaPMuLyRk-_BLZXUk8_U6FyxvKHbI0NPgddFWl_-nLZuCc6HbHg8kaLMDJiO7sHFS8THAuV132xgri8uQ9YV4g8zDXJySrKsSTNiDq9HcXpzUQXQlPy8bTaxZ3gyRxyCy3p
2020-01-17 19:03:08.018870-0800 native[4475:1291684] 6.15.0 - [Firebase/InstanceID][I-IID014001] Token fetch successful, token: ebz2ACPpBkg0kGsgs9yF7_:APA91bGErCaPMuLyRk-_BLZXUk8_U6FyxvKHbI0NPgddFWl_-nLZuCc6HbHg8kaLMDJiO7sHFS8THAuV132xgri8uQ9YV4g8zDXJySrKsSTNiDq9HcXpzUQXQlPy8bTaxZ3gyRxyCy3p, authorizedEntity: 255558254149, scope:*
2020-01-17 19:03:08.019018-0800 native[4475:1291684] 6.15.0 - [Firebase/InstanceID][I-IID003010] Successfully fetched default token.
2020-01-17 19:03:08.019065-0800 native[4475:1291684] 6.15.0 - [Firebase/InstanceID][I-IID003008] Got default token ebz2ACPpBkg0kGsgs9yF7_:APA91bGErCaPMuLyRk-_BLZXUk8_U6FyxvKHbI0NPgddFWl_-nLZuCc6HbHg8kaLMDJiO7sHFS8THAuV132xgri8uQ9YV4g8zDXJySrKsSTNiDq9HcXpzUQXQlPy8bTaxZ3gyRxyCy3p
刚刚在日志中找到了这个利息声明:
在检索发件人ID '255558254149‘的FCM令牌之前,APNS设备令牌未设置。此FCM令牌的通知不会在APNS.Be上传递,一旦APNS设备令牌被设置,肯定会重新检索FCM令牌。
很难相信这种情况会持续发生,但似乎确实是这样,任何帮助都将是非常感谢的。
发布于 2020-01-18 06:34:09
最后,我发现了一个很好的提示,这里
似乎使用react本机的Firebase.messaging().getToken()并不总是返回最新的令牌使用onTokenRefresh。我的应用程序是保存和使用一个旧的令牌,而不是更新一个新的-非常小的比赛条件。 只需使用Firebase.messaging.onTokenRefresh()作为真相的来源,以避免迁移应用程序的问题。另外,为了确保您得到了一个有效的令牌。您可能希望在迁移时删除令牌,比如使用v4 ->进行等待Firebase.iid().deleteToken()或v5 (Firebase.messaging().deleteToken() )。然后依靠onTokenRefresh发送一个新的发送到您的服务器。
现在,在上述引文中提到的firebase.messaging().deleteToken()
并不“足够好”,当TestFlight或Apple有一个应用更新时,就会产生一个tokenRefresh。
我不得不调用异步(当涉及到这个问题时,一切都是异步的,这是经验法则):
firebase.iid().delete();
这个React Native Firebase
api方法删除了InstanceId,这是用于令牌的真正用途。
这将触发onTokenRefresh。因此,我所做的是检查应用程序的版本和构建号,并将其存储在应用程序用户数据(NSDefaults for iOS)中,检查该版本和构建是否存在,如果它没有“刷新”设备令牌。这样只会发生一次。
我将添加我的代码,希望它能帮助其他人解决这个问题,从本质上说,从我的研究来看,使用5.x --这是通过iOS应用程序更新使用Firebase消息来维护无缝推送通知注册的方法:
在App.js中添加以下内容:
configureFirebaseCloudMessaging = async () => {
//wire up Firebase Cloud Messaging onTokenRefresh listener
this.fcmOnTokenRefreshUnsubscribe = await firebase.messaging().onTokenRefresh(async fcmToken => {
console.log('*********************** onTokenRefresh *****************');
//this is callBack called typically sometime in the future but can be call with app loaded but user not logged in
//check for that case and exit if there is no accessToken to call APIs
const accessToken = await AsyncStorage.getItem('access-token');
if (!accessToken) {
console.log('************** user is not logged in exit onTokenRefresh do not register device ************');
return;
}
await this.registerDevice(fcmToken, BASE_URL);
await AsyncStorage.setItem('fcmToken', fcmToken);
firebase.crashlytics().log(`flushed new fcmToken: ${fcmToken}`);
console.log('***************** success account updated with latest token **************');
});
//Firebase Cloud Messaging time
await this.requestPushPermission();
await this.checkFlushv();
}
checkFlushv = async () => {
let FLUSHV = `${DeviceInfo.getVersion()}-build-${DeviceInfo.getBuildNumber()}`;
const flush = await AsyncStorage.getItem(FLUSHV);
console.log('======= checking FLUSHV=========', flush);
if (flush) {
console.log('***** device token already been flushed ******');
return;
}
const accessToken = await AsyncStorage.getItem('access-token');
console.log('flushy access token:', accessToken);
if (!accessToken) {
console.log('******** user is not logged in do not flush ************');
return;
}
//force push notifications, this will fire onTokenRefresh callback
await firebase.iid().delete();
//iterate all keys and remove other builds to keep tidy and TestFlighters possibly going up and back down build versions for testing
const keys = await AsyncStorage.getAllKeys();
const buildKeys = keys.filter(key => {
return key.indexOf('build') !== -1;
});
await AsyncStorage.multiRemove(buildKeys);
//add current build key so no more flushy
await AsyncStorage.setItem(FLUSHV, FLUSHV);
console.log(`=================FLUSHV clear: ${FLUSHV}===================`)
}
registerDevice = async (token, baseUrl) => {
console.log(`******** registerDevice token: ${token}, baseUrl: ${baseUrl}`);
let data = {
device: 'firebase',
token: token
}
//register token with account
axios.post(`${baseUrl}/myapi/register_device`, data)
.then(response => {
return {}
})
.catch(err => {
console.log(err)
return {}
})
}
然后在你的App.js中:
async componentDidUpdate() {
//a new version of the app could be loaded post/after App.componentDidMount
await this.checkFlushv();
}
async componentWillUnmount() {
console.log('app componentWillUnmount');
this.fcmOnTokenRefreshUnsubscribe(); //not really sure unsubcribe is needed but keeping tidy
this.fcmOnTokenRefreshUnsubscribe = null;
}
async componentDidMount() {
await this.configureFirebaseCloudMessaging();
}
发布于 2020-02-28 14:30:21
在找到解决方案之前我花了很多时间。
因此,如果在firebase.iid().delete()
中调用iOS,则需要在APN中注册新令牌。我在本机firebase文档中没有看到这种情况,只是在lib的类型中找到了
await firebase.messaging().ios.registerForRemoteNotifications()
请在生成新令牌后调用此方法。
https://stackoverflow.com/questions/59796431
复制相似问题