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); // 后续逻辑写在这里,每次数据更新都会执行 });
额外注意点
map+async的坑:array.map(async () => {})会返回一个Promise数组,必须用Promise.all()等待所有Promise完成,否则你拿到的只是一堆未resolved的Promise,不是实际数据。- 原代码的判断错误:你写的
if (snapshot.val() != null || snapshot.val() != undefined)逻辑有问题——null != undefined本身是false,而且用Firebase的snapshot.exists()方法更简洁可靠。
内容的提问来源于stack exchange,提问作者Manspof
相关产品推荐
相关产品推荐

