微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Node JS / Firebase Admin SDK / Firestore - 使用快照接收 Firebase 文档后获取空数组 问题建议

如何解决Node JS / Firebase Admin SDK / Firestore - 使用快照接收 Firebase 文档后获取空数组 问题建议

我正在尝试检索 firebase 文档,并使用 snapshot.forEach 块获取指向该文档的关联图像的签名 URL。我将接收到的内容和签名的 url 推送到一个数组中,以便在执行 forEach 块后将整个数组返回到我的角度前端。

我正在使用 firebase admin-sdk 生成存储桶引用 - 'storageRef'。

但是由于某种原因,我在前端收到的新闻列表数组似乎是空的。有人可以让我知道这里出了什么问题吗?

exports.getContents = async(req,res,next) => {

  var newslist = [];
  // Get the contents of each document
  var snapshot = await db.collection('Feeds').doc(req.query.language).collection(req.query.type).get();
  snapshot.forEach((doc) => {

      storageRef.file("thumbnail/" + req.query.type + "/" + doc.id + ".png").getSignedUrl({
        action: 'read',expires: '12-12-2025'
      }).then(signedUrls => {
        newslist.push({
          author: doc._fieldsProto.author,cat: doc._fieldsProto.cat,content: doc._fieldsProto.content,createdAt: doc._fieldsProto.createdAt,excerpt: doc._fieldsProto.excerpt,id: doc.id,imageSrc: signedUrls[0],lastEdit: doc._fieldsProto.lastEdit,media: doc._fieldsProto.media,os_android: doc._fieldsProto.os_android,os_ios: doc._fieldsProto.os_ios,region: doc._fieldsProto.region,status: doc._fieldsProto.status,title: doc._fieldsProto.title,type: doc._fieldsProto.type
          });
      }).catch(error => {
        console.log(error);
      });
  });
  res.json({
    message: "Feeds retrieved successfully",Feeds: newslist
  });
}

解决方法

问题

forEach 循环中,有一个 Promise storageRef.file,后跟一个 then 块,该块仅在 Promise 解决后才执行。

这意味着这个块:

 res.json({
    message: "Feeds retrieved successfully",feeds: newslist
  });

then循环中的任何forEach块之前执行,因此newlist数组为空。

建议

我们将使用 Promise.all 并行执行上述所有异步函数,等待所有 promise 解决,然后继续该过程。

代码如下:

exports.getContents = async(req,res,next) => {

try {

  var newslist = [];
  // Get the contents of each document
  var snapshot = await db.collection('feeds').doc(req.query.language).collection(req.query.type).get();

  var promiseSet = snapshot.map(item => getSignedUrlPromise(req,item)); 
  var signedUrlsSet = await Promise.all(promiseSet);
  
  for(let i = 0; i < snapshot.length; i = i + 1) {

        let doc = snapshop[i];
        let signedUrls = signedUrlsSet[i];
 
        newslist.push({
          author: doc._fieldsProto.author,cat: doc._fieldsProto.cat,content: doc._fieldsProto.content,createdAt: doc._fieldsProto.createdAt,excerpt: doc._fieldsProto.excerpt,id: doc.id,imageSrc: signedUrls[0],lastEdit: doc._fieldsProto.lastEdit,media: doc._fieldsProto.media,os_android: doc._fieldsProto.os_android,os_ios: doc._fieldsProto.os_ios,region: doc._fieldsProto.region,status: doc._fieldsProto.status,title: doc._fieldsProto.title,type: doc._fieldsProto.type
        });
   }
 
  res.json({
    message: "Feeds retrieved successfully",feeds: newslist
  });
 } catch (error) {
    console.log(error);
 }
}

function getSignedUrlPromise(req,doc) {
   return storageRef.file("thumbnail/" + req.query.type + "/" + doc.id + ".png").getSignedUrl({
        action: 'read',expires: '12-12-2025'
      })
}

签出 Promise.all 文档 here

,

感谢@Đăng Khoa Đinh。我用你的逻辑找到了一个可行的解决方案。这是我的代码

const db = admin.firestore(); 
var storageRef = admin.storage().bucket();

exports.getContents = async(req,next) => {

  newslist = []; let i = 0;
  // Print the ID and contents of each document
  var snapshot = await db.collection('feeds').doc(req.query.language).collection(req.query.type).get();
  var promiseSet = snapshot.docs.map(item => getSignedUrl(req.query.type,item.id)); 
  var signedUrlsSet = await Promise.all(promiseSet);
  snapshot.forEach((doc) => {
    let signedUrls = signedUrlsSet[i];
    newslist.push({
      author: doc._fieldsProto.author,type: doc._fieldsProto.type
    });
    i++;
  });
  res.json({
    message: "Feeds retrieved successfully",feeds: newslist
  });
 }

这是我的 getSignedUrl 函数

function getSignedUrl(req,doc) {
  return storageRef.file("thumbnail/" + req + "/" + doc + ".png").getSignedUrl({
    action: 'read',expires: '12-12-2025'
  });
} 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。