Firebase基于主题的推送通知重复问题排查求助
生产环境Firebase主题推送重复通知排查问题
背景与实现方案
我们采用Firebase Functions(TypeScript)实现即时触发与定时触发的推送通知,随着用户规模增长,切换为基于主题(Topic)的推送方案,移动端负责主题的创建、订阅与退订逻辑。
关键代码片段
1. 移动端主题订阅/退订逻辑
if (name !== undefined) { const nameLower = name.toLowerCase() if (countryName) { isSubscribe ? await messaging().subscribeToTopic(nameLower) : await messaging().unsubscribeFromTopic(nameLower) } } if (platform) { isSubscribe ? await messaging().subscribeToTopic(platform) : await messaging().unsubscribeFromTopic(platform) } mIds?.forEach(async element => { if (element) { isSubscribe ? await messaging().subscribeToTopic(element) : await messaging().unsubscribeFromTopic(element) } }); arrIds?.forEach(async element => { const createTopic = `${element?.tId}-${element?.rId}` if (createTopic) { isSubscribe ? await messaging().subscribeToTopic(createTopic) : await messaging().unsubscribeFromTopic(createTopic) } });
2. 移动端通知处理(NotificationCenter.ts)
useEffect(() => { // 前台通知展示 const unsubscribe = messaging().onMessage((remoteMessage) => { if (remoteMessage.notification) { showMessage({ message: remoteMessage.notification.title, description: remoteMessage.notification.body, type: "success", duration: 3000, statusBarHeight: StatusBar.currentHeight, onPress: () => { remoteMessage?.data?.Id && details(remoteMessage?.data?.Id) }, }) } }) return () => { unsubscribe() } }, []) useEffect(() => { // iOS角标清零 return notifee.onForegroundEvent(({ type, detail }) => { switch (type) { case EventType.PRESS: notifee.setBadgeCount(0) detail.notification?.data && details(detail.notification?.data?.Id as string) break } }) }, []) useEffect(() => { // 应用冷启动时处理初始通知 messaging() .getInitialNotification() .then((remoteMessage) => { if (remoteMessage) { remoteMessage.data.Id && details(remoteMessage.data.Id) } }) }, []) useEffect(() => { // 应用后台时点击通知打开应用的处理 messaging().onNotificationOpenedApp((remoteMessage) => { remoteMessage.data.Id && details(remoteMessage.data.Id) }) }, []) const details = (Id: string) => { // 详情页跳转逻辑 client.notificationDetails(true) navigate("detailsScreen", { Id }) }
3. 云函数动态构建推送条件并发送通知
// 动态构建推送条件 if (global.length > 0) { condition = `'${data?.IdString}' in topics`; } else { condition = fireb.docs.reduce( (cnd, data, i) => `${cnd}${i > 0 ? ' || ' : ''}'${details?.Id[0]}-${ data.data().refId }' in topics`, '', ); // 示例条件:"xxxxxxx-xxxxx-<firebase doc id>' in topics || 'xxxxxxx-xxxxx-<firebase doc id>' in topics" } const message = { notification: { title: `${name} - ${title}`, body: details?.heading?.body, }, apns: { payload: { aps: { sound: 'default', badge: 1, }, }, }, data: {refId: `${data?.Id}`}, condition: condition, // 动态生成的条件 }; // 发送主题推送 const response = await admin.messaging().send(message);
问题现象
测试与预发布环境(用户及主题数量较少)未出现重复通知问题,但生产环境(订阅用户规模1k-10k)偶尔出现重复通知:今日推送的10条通知中,有2条出现重复,一条重复4次,另一条重复2次。已确认云函数日志仅触发一次,无重复执行记录。
求助需求
排查代码中是否存在导致重复通知的bug,或是Firebase Admin SDK层面的问题?
内容的提问来源于stack exchange,提问作者Fahry Mohammed
相关产品推荐
相关产品推荐

