如何为同一Firebase用户存储多个FCM注册令牌?
解决方案:存储多设备FCM令牌列表并在Node.js中使用
当然可以实现!你只需要将Firestore中存储单个令牌的字段,改成数组类型来保存用户的所有设备令牌。这样同一用户在不同设备登录时,新令牌会被添加到数组中,而不是覆盖旧的。下面是具体的实现步骤:
1. 修改Android端的令牌存储代码
原来的代码使用update()直接覆盖token_id字段,现在我们改用Firestore的arrayUnion()方法来添加新令牌(这个方法会自动忽略数组中已存在的令牌,避免重复存储)。修改后的代码如下:
String token_id = FirebaseInstanceId.getInstance().getToken(); Log.i("token_id", token_id); // 使用arrayUnion将新令牌添加到数组中,而不是覆盖 Map<String, Object> tokenMap = new HashMap<>(); tokenMap.put("token_ids", FieldValue.arrayUnion(token_id)); mFireStore.collection("Users").document(current_id) .update(tokenMap) .addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void aVoid) { Toast.makeText(LoginActivity.this, "Signed in Successfully", Toast.LENGTH_SHORT).show(); startActivity(new Intent(LoginActivity.this, AdminActivity.class)); finish(); } });
注意:需要确保导入
com.google.firebase.firestore.FieldValue类。如果是首次存储用户的令牌,数组会自动创建并添加第一个元素;如果已有数组,新令牌会被追加进去。
2. Firestore文档结构变化
修改后,你的Users集合中的文档结构会变成这样:
{ "current_id": "用户唯一ID", "token_ids": [ "设备1的FCM令牌", "设备2的FCM令牌", "设备3的FCM令牌" ], // 其他用户字段... }
3. 在Node.js函数中使用令牌列表发送通知
当你需要给用户发送通知时,可以从Firestore读取该用户的token_ids数组,然后遍历数组给每个设备发送通知,或者使用FCM的批量发送功能。以下是Node.js的示例代码:
const admin = require('firebase-admin'); admin.initializeApp(); // 给指定用户发送通知的函数 async function sendNotificationToUser(userId, notificationPayload) { try { // 从Firestore获取用户的令牌列表 const userDoc = await admin.firestore().collection('Users').doc(userId).get(); if (!userDoc.exists) { console.log('用户不存在'); return; } const tokenIds = userDoc.data().token_ids; if (!tokenIds || tokenIds.length === 0) { console.log('该用户没有可用的设备令牌'); return; } // 给每个令牌发送通知 const responses = await admin.messaging().sendEachForMulticast({ tokens: tokenIds, notification: notificationPayload }); console.log(`成功发送 ${responses.successCount} 条通知,失败 ${responses.failureCount} 条`); // 可以在这里处理失败的令牌(比如移除无效令牌) responses.responses.forEach((response, index) => { if (!response.success) { console.error(`令牌 ${tokenIds[index]} 发送失败: ${response.error}`); // 可选:移除无效令牌 // admin.firestore().collection('Users').doc(userId).update({ // token_ids: admin.firestore.FieldValue.arrayRemove(tokenIds[index]) // }); } }); } catch (error) { console.error('发送通知失败:', error); } } // 使用示例 sendNotificationToUser('用户的current_id', { title: '新通知', body: '你有一条新消息' });
补充:如果用户在某台设备上注销,你可以调用
FieldValue.arrayRemove(token_id)来从数组中移除对应的令牌,避免向无效设备发送通知。
内容的提问来源于stack exchange,提问作者rituparna
相关产品推荐
相关产品推荐

