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

如何向多设备发送Expo推送通知?Firestore取token单设备接收问题

Expo推送通知仅能推送给单台设备的问题修复

问题根源

  1. React setState异步特性导致取值错误:调用setRead后立即读取read变量,此时read尚未完成更新,导致readx拿到的是旧数据而非完整的令牌数组。
  2. 错误格式化令牌数组:Expo推送API的to字段支持单个令牌字符串或令牌数组,你用JSON.stringify将数组转为字符串后,API无法识别为多设备列表,仅会处理字符串中的第一个有效令牌。

修复代码

修正推送函数

async function sendPushNotification(tokens) {
  const message = {
    to: tokens, // 直接传入令牌数组,无需JSON转换
    sound: "default",
    title: "Original Title",
    body: "And here is the body!",
    data: { someData: "goes here" },
  };

  // 调用Expo推送API发送消息(补充你可能遗漏的发送逻辑)
  await fetch('https://exp.host/--/api/v2/push/send', {
    method: 'POST',
    headers: {
      Accept: 'application/json',
      'Accept-encoding': 'gzip, deflate',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(message),
  });
}

修正令牌获取函数

方案一:直接在获取令牌后调用推送,避开setState异步问题

const retrieveNetwork = async () => {
  try {
    const q = query(collection(db, "users"));
    const querySnapshot = await getDocs(q);
    const tokens = querySnapshot.docs.map((doc) => doc.data().expoUser);
    setRead(tokens);
    // 直接推送,无需依赖state更新
    await sendPushNotification(tokens);
  } catch (e) {
    alert(e);
  }
};

方案二:用useEffect监听state变化,确保令牌更新后再推送

const retrieveNetwork = async () => {
  try {
    const q = query(collection(db, "users"));
    const querySnapshot = await getDocs(q);
    const tokens = querySnapshot.docs.map((doc) => doc.data().expoUser);
    setRead(tokens);
  } catch (e) {
    alert(e);
  }
};

// 监听read状态变化,更新后触发推送
useEffect(() => {
  if (read.length > 0) {
    sendPushNotification(read);
  }
}, [read]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 03:05:48