如何管理 FCM 推送令牌
How to manage FCM push tokens
我想找到一个可持续的解决方案来存储用于推送通知的 FCM 令牌。我正在将 React Native 与 Firebase 结合使用。
要求是:
- 基于用户的应用程序
- 每个用户支持多个设备
- 任何时候都没有存储过时的令牌。
我目前的做法是:
维护一个 table user_devices
列:
- user_id,
- device_uuid
- fcm_token
维护 fcm_token 和 device_uuid 的唯一性约束。
发生关键事件,包括但不限于:
- 应用程序启动
- 登录
- onTokenRefresh
将以下内容发送到后端:
- device unique id
- FCM 注册令牌
- 用户 ID,如果有(通过身份验证令牌完成)
后端然后用上述值插入一行。如果设备 uuid 存在,这意味着我们将覆盖该设备 uuid 的令牌(可能还有 user_id)。
上述方法存在缺陷,因为:
- device unique id 可以随时更改(设备重置、更新、应用重新安装等...)
- 注册令牌可以随时更改
换句话说,table 最终存储了许多过时的令牌,应用程序后端向这些过时的令牌发送通知。
此外,“设备”前端页面(向用户显示他们注册的设备并从上面读取 table)显示许多重复的设备,它们实际上代表相同的设备但具有不同的设备 uuid。
一个缓解步骤可能是定期向存储在 table 和 dry_run=true
中的所有令牌发送通知。然后,删除包含发生错误的标记的行。这很糟糕,因为它意味着 table.
中有一段时间令牌过时
我已经在线浏览了多种资源,包括 FCM 文档,但没有提及在实际应用程序中存储和维护这些令牌。有什么建议的方法吗?
惯用的方法是当 Firebase Cloud Messaging API 发送消息时告诉您令牌无效时删除令牌。
有关如何执行此操作的示例,您可以查看 sending notifications 的 Cloud Functions 示例,它执行以下操作:
const response = await admin.messaging().sendToDevice(tokens, payload);
// For each message check if there was an error.
const tokensToRemove = [];
response.results.forEach((result, index) => {
const error = result.error;
if (error) {
functions.logger.error(
'Failure sending notification to',
tokens[index],
error
);
// Cleanup the tokens who are not registered anymore.
if (error.code === 'messaging/invalid-registration-token' ||
error.code === 'messaging/registration-token-not-registered') {
tokensToRemove.push(tokensSnapshot.ref.child(tokens[index]).remove());
}
}
});
return Promise.all(tokensToRemove);
因此,每次您通过 FCM 发送一条或多条消息时,您都会从数据库中剔除 invalid/outdated 个令牌。
我想找到一个可持续的解决方案来存储用于推送通知的 FCM 令牌。我正在将 React Native 与 Firebase 结合使用。
要求是:
- 基于用户的应用程序
- 每个用户支持多个设备
- 任何时候都没有存储过时的令牌。
我目前的做法是:
维护一个 table user_devices
列:
- user_id,
- device_uuid
- fcm_token
维护 fcm_token 和 device_uuid 的唯一性约束。
发生关键事件,包括但不限于:
- 应用程序启动
- 登录
- onTokenRefresh
将以下内容发送到后端:
- device unique id
- FCM 注册令牌
- 用户 ID,如果有(通过身份验证令牌完成)
后端然后用上述值插入一行。如果设备 uuid 存在,这意味着我们将覆盖该设备 uuid 的令牌(可能还有 user_id)。
上述方法存在缺陷,因为:
- device unique id 可以随时更改(设备重置、更新、应用重新安装等...)
- 注册令牌可以随时更改
换句话说,table 最终存储了许多过时的令牌,应用程序后端向这些过时的令牌发送通知。
此外,“设备”前端页面(向用户显示他们注册的设备并从上面读取 table)显示许多重复的设备,它们实际上代表相同的设备但具有不同的设备 uuid。
一个缓解步骤可能是定期向存储在 table 和 dry_run=true
中的所有令牌发送通知。然后,删除包含发生错误的标记的行。这很糟糕,因为它意味着 table.
我已经在线浏览了多种资源,包括 FCM 文档,但没有提及在实际应用程序中存储和维护这些令牌。有什么建议的方法吗?
惯用的方法是当 Firebase Cloud Messaging API 发送消息时告诉您令牌无效时删除令牌。
有关如何执行此操作的示例,您可以查看 sending notifications 的 Cloud Functions 示例,它执行以下操作:
const response = await admin.messaging().sendToDevice(tokens, payload);
// For each message check if there was an error.
const tokensToRemove = [];
response.results.forEach((result, index) => {
const error = result.error;
if (error) {
functions.logger.error(
'Failure sending notification to',
tokens[index],
error
);
// Cleanup the tokens who are not registered anymore.
if (error.code === 'messaging/invalid-registration-token' ||
error.code === 'messaging/registration-token-not-registered') {
tokensToRemove.push(tokensSnapshot.ref.child(tokens[index]).remove());
}
}
});
return Promise.all(tokensToRemove);
因此,每次您通过 FCM 发送一条或多条消息时,您都会从数据库中剔除 invalid/outdated 个令牌。