Node JS / Firebase Admin SDK / Firestore - Getting empty array after receiving firebase documents using snapshots

248 views Asked by At

I'm trying to retrieve firebase documents and also get a signed URL to the associated image for that doc using snapshot.forEach block. I'm pushing the contents and the signed url as i receive them into an array so that i can return the whole array to my angular frontend after the forEach block is executed.

I'm using the firebase admin-sdk to generate the bucket reference - 'storageRef'.

But the newslist array that i receive in frontend seems to be empty for some reason. Can someone let me know what is going wrong here?

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
  });
}
1

There are 1 answers

0
Jefin George Jose On BEST ANSWER

Thanks @Đăng Khoa Đinh. I used your logic to find a working solution. Here is my code

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

exports.getContents = async(req, res, 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,
      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
    });
    i++;
  });
  res.json({
    message: "Feeds retrieved successfully",
    feeds: newslist
  });
 }

Here is my getSignedUrl function

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