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

Firebase on('value')搭配await未按预期工作的问题求助

解决Firebase on('value') 无法用await等待的问题

你遇到的核心问题是:firebase.database().ref().on('value') 是实时监听方法,它不会返回Promise,所以用await调用它完全无效——代码会直接跳过等待,继续执行后续逻辑,这就是t2先于t1输出的原因。

下面分两种场景给你针对性解决方案:


场景1:只需要一次性获取数据(无需实时监听变化)

如果你的需求是获取一次UpcomingGames的数据,再处理每个游戏的偏好设置,直接用once('value')代替on('value')即可,因为once返回Promise,能正常用await等待:

async function fetchUpcomingGamesWithPreferences() {
  // 一次性获取UpcomingGames数据
  const snapshot = await firebase.database().ref('UpcomingGames').once('value');
  let upcomingGamesList = snapshot.val();
  console.log('upcoming t1', upcomingGamesList);

  // 处理每个游戏的偏好设置:map返回Promise数组,必须用Promise.all等待全部完成
  const updatedList = await Promise.all(upcomingGamesList.map(async (game) => {
    console.log('Processing game:', game);
    const GameId = game.GameId;
    const prefSnapshot = await firebase.database()
      .ref(`GameNotificationPreferances/${GameId}`)
      .orderByKey()
      .equalTo(UserStore.user.uid)
      .once('value');

    // 用Firebase自带的exists()判断数据是否存在,比手动判null/undefined更可靠
    game['reminderPressed'] = prefSnapshot.exists();
    console.log('GameId:', GameId, 'Updated details:', game);
    return {...game};
  }));

  console.log('Final updated list:', updatedList);
  // 后续逻辑写在这里即可
}

// 调用函数
fetchUpcomingGamesWithPreferences();

场景2:需要实时监听UpcomingGames的变化(数据更新时自动重新处理)

如果你的需求是每次UpcomingGames数据变化时,都重新获取并处理偏好设置,那就要保留on('value'),但把所有后续逻辑放到它的回调函数里,不要用await包裹监听方法:

// 监听UpcomingGames的实时变化
firebase.database().ref('UpcomingGames').on('value', async (snapshot) => {
  let upcomingGamesList = snapshot.val();
  console.log('Upcoming games updated:', upcomingGamesList);

  // 处理所有游戏的偏好设置,同样用Promise.all等待全部完成
  const updatedList = await Promise.all(upcomingGamesList.map(async (game) => {
    const GameId = game.GameId;
    const prefSnapshot = await firebase.database()
      .ref(`GameNotificationPreferances/${GameId}`)
      .orderByKey()
      .equalTo(UserStore.user.uid)
      .once('value');

    game['reminderPressed'] = prefSnapshot.exists();
    console.log('GameId:', GameId, 'Updated details:', game);
    return {...game};
  }));

  console.log('the updatedList is', updatedList);
  // 后续逻辑写在这里,每次数据更新都会执行
});

额外注意点

  1. map+async的坑:array.map(async () => {})会返回一个Promise数组,必须用Promise.all()等待所有Promise完成,否则你拿到的只是一堆未resolved的Promise,不是实际数据。
  2. 原代码的判断错误:你写的if (snapshot.val() != null || snapshot.val() != undefined)逻辑有问题——null != undefined本身是false,而且用Firebase的snapshot.exists()方法更简洁可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:55:42