如何基于Firebase+React Native实现特定用户的FCM商品降价推送?
实现FCM向对应用户推送降价通知的步骤
1. 绑定用户FCM令牌与userID并存储
FCM是通过设备令牌推送通知的,你需要先把用户的设备令牌和对应的userID关联起来存在Firestore里,这样后续才能通过userID找到要推送的设备。
在React Native项目中,借助@react-native-firebase/messaging获取令牌并存储:
import messaging from '@react-native-firebase/messaging'; import firestore from '@react-native-firebase/firestore'; async function syncFCMToken(userId) { const fcmToken = await messaging().getToken(); if (fcmToken) { // 将令牌添加到用户文档的fcmTokens数组中(避免重复存储) await firestore() .collection('users') .doc(userId) .set( { fcmTokens: firestore.FieldValue.arrayUnion(fcmToken) }, { merge: true } ); } }
调用时机:用户登录成功后、APP每次启动时都要执行,因为设备令牌可能因卸载重装、更换设备等情况发生变化。
2. 匹配降价商品后,获取目标用户的FCM令牌
假设你的Firestore结构是:
users集合:存储用户基础信息,每个文档包含fcmTokens数组字段userFollowedProducts集合:记录用户关注的商品,文档结构为{ userId: 'xxx', productId: 'xxx', productName: 'xxx' }
匹配到降价商品后,先找出所有关注该商品的用户,再批量提取他们的FCM令牌:
// 在Firebase Cloud Functions中执行 const admin = require('firebase-admin'); admin.initializeApp(); async function getTargetTokens(discountedProductId) { // 查询所有关注该商品的用户ID const followSnapshot = await admin.firestore() .collection('userFollowedProducts') .where('productId', '==', discountedProductId) .get(); const userIds = followSnapshot.docs.map(doc => doc.data().userId); if (userIds.length === 0) return []; // 批量获取这些用户的FCM令牌 const userSnapshot = await admin.firestore() .collection('users') .where(admin.firestore.FieldPath.documentId(), 'in', userIds) .get(); let tokens = []; userSnapshot.forEach(doc => { const userTokens = doc.data().fcmTokens || []; tokens = [...tokens, ...userTokens]; }); // 去重,避免重复推送 return [...new Set(tokens)]; }
3. 通过Cloud Functions发送批量FCM通知
拿到目标令牌列表后,用Firebase Admin SDK发送批量通知:
async function sendPriceDropAlert(productInfo, targetTokens) { if (targetTokens.length === 0) return; const message = { notification: { title: '商品降价提醒', body: `${productInfo.name} 现已降价,点击查看详情!`, }, tokens: targetTokens, // 可选:添加数据字段,APP端可解析实现跳转等逻辑 data: { productId: productInfo.id, productUrl: productInfo.url, }, }; try { const response = await admin.messaging().sendMulticast(message); console.log(`成功推送 ${response.successCount} 条通知`); // 清理无效令牌(比如用户卸载APP后令牌失效) const failedTokens = []; response.responses.forEach((resp, idx) => { if (!resp.success) failedTokens.push(targetTokens[idx]); }); if (failedTokens.length > 0) { const userDocs = await admin.firestore().collection('users').get(); userDocs.forEach(async doc => { const currentTokens = doc.data().fcmTokens || []; const updatedTokens = currentTokens.filter(token => !failedTokens.includes(token)); await doc.ref.update({ fcmTokens: updatedTokens }); }); } } catch (err) { console.error('推送通知失败:', err); } }
额外注意事项
- 令牌更新机制:必须在APP启动时同步令牌,避免因令牌过期导致推送失败。
- 批量推送限制:FCM的
sendMulticast单次最多支持500个令牌,若目标用户超过500,需拆分批次发送。 - 权限配置:确保Cloud Functions拥有Firestore读写权限和FCM发送权限(初始化Admin SDK后默认具备)。
内容的提问来源于stack exchange,提问作者JUNSKI
相关产品推荐
相关产品推荐

