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

如何在Cloud Function中查询Firestore实现动态推送通知

动态获取Firestore用户Token实现推送通知的Cloud Function改造方案

需求回顾

当「chat messages」集合新增消息时,需完成以下流程:

  • 提取新增消息的「Chat id」和发送者「User id」
  • 通过「Chat id」查询「chat」集合对应文档,从「Job users data」数组中筛选出接收消息的用户ID(排除发送者)
  • 从「User tokens」集合(以用户ID为文档ID)中获取接收者的推送Token
  • 使用该Token发送推送通知

改造后的完整Cloud Function代码

const functions = require("firebase-functions");
const admin = require("firebase-admin");

admin.initializeApp();

exports.onChatMessageCreate = functions.firestore
  .document("chat messages/{docId}")
  .onCreate(async (snapshot, context) => {
    try {
      const messageData = snapshot.data();
      console.log("新增消息数据:", messageData);

      // 1. 提取消息中的Chat id和发送者User id
      const chatId = messageData["Chat id"];
      const senderUserId = messageData["User id"];

      if (!chatId || !senderUserId) {
        console.log("缺少必要的Chat id或User id字段");
        return;
      }

      // 2. 查询chat集合对应的文档,获取Job users data数组
      const chatDoc = await admin.firestore().collection("chat").doc(chatId).get();
      if (!chatDoc.exists) {
        console.log(`Chat id为${chatId}的文档不存在`);
        return;
      }

      const chatData = chatDoc.data();
      const jobUsersData = chatData["Job users data"];
      if (!Array.isArray(jobUsersData) || jobUsersData.length < 2) {
        console.log("Job users data格式不正确");
        return;
      }

      // 筛选出接收者的userId(排除发送者)
      const receiverUser = jobUsersData.find(user => user.userId !== senderUserId);
      if (!receiverUser) {
        console.log("未找到接收者用户");
        return;
      }
      const receiverUserId = receiverUser.userId;

      // 3. 查询User tokens集合获取接收者的推送Token
      const tokenDoc = await admin.firestore().collection("User tokens").doc(receiverUserId).get();
      if (!tokenDoc.exists) {
        console.log(`用户${receiverUserId}未存储推送Token`);
        return;
      }

      const receiverToken = tokenDoc.data().token;
      if (!receiverToken) {
        console.log(`用户${receiverUserId}的Token为空`);
        return;
      }

      // 4. 构造推送Payload并发送通知
      const payload = {
        notification: {
          title: messageData["userName"],
          body: messageData["Chat message"],
          sound: "default"
        },
        data: {
          click_action: "FLUTTER_NOTIFICATION_CLICK",
          message: messageData["Chat message"]
        }
      };

      await admin.messaging().sendToDevice(receiverToken, payload);
      console.log(`通知已成功发送给用户${receiverUserId}`);

    } catch (e) {
      console.log("发送通知时出错:", e);
    }
  });

关键改动说明

  1. 异步处理:将函数改为async,用await处理所有Firestore查询,确保流程按顺序执行
  2. 数据校验:每一步添加必要校验(字段存在性、文档存在性、数组格式),避免数据异常导致崩溃
  3. 动态Token获取:
    • 从消息中取Chat id查询对应chat文档,筛选出接收者ID
    • 用接收者ID作为文档ID,查询「User tokens」集合获取推送Token
  4. Payload优化:将data中的消息内容替换为实际新增的消息文本,保证跳转后信息准确
  5. 统一错误处理:用try/catch包裹全逻辑,便于异常排查

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 03:05:18