如何将Firebase Realtime DB查询结果作为生成Signed URL的输入
问题排查与解决思路
核心故障原因
你代码中使用的on('child_added')是Firebase Realtime Database的流式事件监听器,不会返回Promise对象,因此await关键字对它无效。代码会直接跳过数据加载逻辑执行后续的签名URL生成步骤,此时lista数组还未被查询结果填充,自然不会输出预期结果。
排查步骤
- 验证数据加载时机:在生成签名URL的for循环前添加打印代码
console.log('查询到的文件数量:', lista.length),如果输出为0,即可确认是数据未加载完成就执行了后续逻辑。 - 验证查询权限:检查Realtime Database的安全规则,确认当前执行环境的账号有对应数据路径的读取权限,权限不足会导致查询无返回结果。
- 验证查询参数合法性:确认
timestamp1、timestamp2是和数据库中timestamp_start字段格式一致的毫秒级时间戳,且时间区间内存在匹配的记录。
修复代码
将流式事件监听替换为一次性全量查询接口once('value'),该接口会返回Promise,可正常被await等待执行完成:
// define the async function that does everything async function queryandgeturls() { // 改用once('value')获取所有匹配数据,支持await等待执行完成 const querySnapshot = await ref.orderByChild('timestamp_start').startAt(timestamp1).endAt(timestamp2).once('value'); const lista = []; // 遍历查询快照提取所有文件名 querySnapshot.forEach(childSnapshot => { lista.push(childSnapshot.val().name); }); // use the list as input for another function to get Signed URLs for (const fileName of lista) { const [signedUrl] = await storage.bucket(bucketName).file(fileName).getSignedUrl({ version: 'v4', expires: Date.now() + 15 * 60 * 1000, action: 'read' }); console.log(`The signed URL for ${fileName} is ${signedUrl}`); } }; // call the function queryandgeturls().catch(console.error);
可选优化
如果需要提升签名URL生成效率,可将串行的for循环替换为Promise.all并行生成,适合文件数量较多的场景。
内容的提问来源于stack exchange,提问作者ashutoshdhanda
相关产品推荐
相关产品推荐

