【问题标题】:loop through documents in a collection to get fields循环遍历集合中的文档以获取字段
【发布时间】:2020-06-30 10:33:47
【问题描述】:

我在 firebase firestore 中有一个名为 users 的集合。集合 users 中的每个文档都是在应用程序中注册的用户。每个文档都有一个名为 token_ids 的字段。如何遍历所有文档以获取 token_ids 字段中的值。我正在使用 Firebase 云功能来做到这一点。这是我尝试使用但不起作用的代码 sn-p:

const functions = require('firebase-functions');
const admin = require ('firebase-admin');
admin.initializeApp();

  //fetch all token ids of users

  const tokenReference = admin.firestore().collection("users");

  const tokenSnapshot  = await tokenReference.get();

  tokenSnapshot.forEach((doc) =>{

    console.log("Token ids are:" + doc.data().token_id);


  });

  });

【问题讨论】:

  • 我没有看到您尝试过的完整代码。
  • 您能否详细说明您对“不工作”的定义是什么,您的预期行为是什么,您当前的行为是什么以及您是如何运行脚本的?

标签: node.js firebase google-cloud-firestore google-cloud-functions


【解决方案1】:

花了我一段时间,但终于找到了解决方案。这里是。这是 Dhruv Shah 给出的第一个解决方案,但稍作修改:

async function fetchAllTTokenIds() {

  const tokenReference = admin.firestore().collection("users");
  
  const tokenSnapshot  = await tokenReference.get();
  const results = [];
  tokenSnapshot.forEach(doc => {

    results.push(doc.data().token_id);

  });

  const tokenIds = await Promise.all(results);

  return console.log("Here =>" +tokenIds);


}


【讨论】:

  • 如果您找到了解决方案,请考虑接受您自己的答案。
【解决方案2】:

由于 Firestore 操作是异步的,因此您最好将代码包装在 async-await 块中。

例如:

async function fetchAllTTokenIds() {

  const tokenReference = admin.firestore().collection("users");
  
  const tokenSnapshot  = await tokenReference.get();
  const results = [];
  // Recommendation: use for-of loops, if you intend to execute asynchronous operations in a loop.
  for(const doc of tokenSnapShot) {
    results.push(doc.data().token_id);
  }
  const tokenIds = await Promise.all(results);
}

通过这种方式,所有tokenIds 变量都将填充tokenIds 的数组。

或者,您也可以并行进行所有异步调用,因为它们使用Promise.all (Reference) 相互独立

async function fetchAllTTokenIds() {

  const tokenReference = admin.firestore().collection("users");
  
  const tokenSnapshot  = await tokenReference.get();

  const tokenIds = await Promise.all(tokenSnapShot.map(doc => {
    return doc.data()
      .then(data => (data.token_id)) 
  }))

在这种情况下,tokenIds 变量将包含所有 tokenId 的数组。

【讨论】:

  • 我尝试了第一个答案。它给出了以下错误:Unexpected await inside a loop
  • 这似乎是一个lint 错误。但是,我已经更新了我的答案并从循环中删除了等待。
  • 第二种解决方案在云函数日志中出现以下错误:TypeError: tokenSnapshot.map is not a function
  • 更新后,我运行了代码,但它给出了这个错误 TypeError: tokenSnapshot is not iterable , in the cloud firestore logs.
【解决方案3】:

代码 sn-p 的结构取决于您使用的是 Firebase Admin SDK,无论是作为在本地计算机上运行的脚本还是由客户端应用调用的 httpsCallable。第一种情况是这样写的:

在你的脚本file.js中,初始化应用后,编写如下代码。

exports.test_f = async function() {
  try {

    const tokenReference = admin.firestore().collection("users");

    const tokenSnapshot  = await tokenReference.get();

    tokenSnapshot.forEach((doc) =>{

      console.log("Token ids are:" + doc.data().token_id);


    });
  } catch (error) {
    console.log(error);
  }
}

exports.test_f();

使用命令node file.js 在命令行上运行此脚本,这将打印提供的输出

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-16
    • 2016-07-16
    • 2014-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多