You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Firebase Database获取所有iOS设备FCM令牌?

如何正确从Firebase Database获取iOS设备令牌数组用于FCM推送

你的问题出在对Firebase DataSnapshot对象的处理上——你直接调用Object.keys(tokensSnapShot),但这个方法拿到的是DataSnapshot自身的内置属性(比如node_、ref_这些),而不是你存储的设备令牌数据。下面是修正后的代码,我会一步步解释关键修改点:

exports.iOSPush = functions.database.ref('/BootCamp/Bulletins/date').onWrite(async (snapShot, context) => {
  // 1. 直接获取iOS令牌节点的完整快照,不需要加{key}通配符
  const tokensSnapshot = await admin.database().ref('/BootCamp/Notifications/iOS').once('value');
  
  // 2. 遍历快照,提取每个子节点中的deviceToken字段
  const tokens = [];
  tokensSnapshot.forEach(childSnapshot => {
    const deviceToken = childSnapshot.val().deviceToken;
    if (deviceToken) { // 过滤空令牌,避免无效推送
      tokens.push(deviceToken);
    }
  });

  if (tokens.length === 0) {
    console.log('没有可用的iOS设备令牌,跳过推送');
    return null;
  }

  // 3. 构建FCM推送 payload
  const payload = {
    notification: {
      title: 'congrats it works',
      body: 'Cloud function noti for ios',
      sound: 'default',
      badge: '1'
    }
  };

  // 4. 发送推送并处理结果
  return admin.messaging().sendToDevice(tokens, payload)
    .then(response => {
      console.log('推送发送成功,结果:', response);
      // 可选:清理失效的令牌(比如过期或注销的设备)
      const cleanupPromises = [];
      response.results.forEach((result, index) => {
        const error = result.error;
        if (error) {
          console.error('推送失败的令牌:', tokens[index], '错误:', error);
          // 针对无效令牌,从数据库中删除
          if (error.code === 'messaging/invalid-registration-token' ||
              error.code === 'messaging/registration-token-not-registered') {
            const tokenKey = Object.keys(tokensSnapshot.val())[index];
            cleanupPromises.push(tokensSnapshot.ref.child(tokenKey).remove());
          }
        }
      });
      return Promise.all(cleanupPromises);
    })
    .catch(error => {
      console.error('推送发送失败:', error);
    });
});

关键修改说明:

  • 修正快照获取路径:去掉了路径中的{key},因为你需要获取/BootCamp/Notifications/iOS下的所有子节点,而不是单个节点。
  • 正确遍历快照数据:使用DataSnapshot的forEach方法遍历每个自动ID子节点,通过childSnapshot.val().deviceToken提取每个节点的令牌值,收集到数组中。
  • 增加空数组校验:先检查令牌数组是否为空,避免调用sendToDevice时传入空数组导致不必要的错误。
  • 可选的失效令牌清理:添加了对无效令牌的处理逻辑,自动删除数据库中过期或失效的令牌,优化后续推送效率。

这样修改后,你就能得到预期的设备令牌数组,正常发送FCM推送了。

内容的提问来源于stack exchange,提问作者KarmaDeli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:34:05