首页 > 解决方案 > 等待 Firebase 查询的所有结果?

问题描述

我会尽力解释这一点,因为我是使用 javascript 和 Firebase SDK 的新手。这是我拥有的模拟数据:

    "Via" : {
    "00zz00" : {
      "coordinates" : "0,0",
      "order_number" : 1,
      "route_id" : "xyz987",
      "via_id" : "00zz00"
    },
    "1a2b3c" : {
      "coordinates" : "10,-10.1",
      "order_number" : 1,
      "route_id" : "abc123",
      "via_id" : "1a2b3c"
    },
    "2b3c4d" : {
      "coordinates" : "45.5,-24.7",
      "order_number" : 2,
      "route_id" : "abc123",
      "via_id" : "2b3c4d"
    },
    "3c4d5e" : {
      "coordinates" : "45.8,-24.0",
      "order_number" : 4,
      "route_id" : "abc123",
      "via_id" : "3c4d5e"
    },
    "4d5e6f" : {
      "coordinates" : "20.0,-20.0",
      "order_number" : 3,
      "route_id" : "abc123",
      "via_id" : "4d5e6f"
    }
  }

我首先使用带有“child_added”事件的 .on() 进行查询,以使用每个结果的坐标填充数组:

var waypoints = new Array();
var refVia = firebase.database().ref("Via");
refVia
    .orderByChild("route_id")
    .equalTo("abc123")
    .on("child_added", function (snapshot) {
        waypoints.push(snapshot.val().coordinates);
    });

我正在调用另一个 API 并使用数组创建路由,但我意识到我收到了一个错误,因为我的数组仍然是空的。我在这里找到了一个解决方案,提到使用 .once().then() 和“价值”事件以及一个承诺,但我对如何从这里开始有点困惑。我试过这个,但我有点迷路了。

var refVia = firebase.database().ref("Via");
    return refVia
        .orderByChild("route_id")
        .equalTo("abc123")
        .once("value")
        .then(
            function (snapshot) {
                var via = [];
                
                //Not sure what to do here to add the entries to my array...

                return Promise.all(via);

            },
            function (error) {
                
                console.error(error);
            }
        );

标签: javascriptfirebasefirebase-realtime-database

解决方案


我知道您需要遍历节点的键(等于子节点via_id值)才能定义添加到via数组的承诺。因此,以下应该可以解决问题:

  var refVia = firebase.database().ref('Via');
  return refVia
    .orderByChild('route_id')
    .equalTo('abc123')
    .once('value')
    .then((snapshot) => {
      const via = [];
      for (const [key, value] of Object.entries(snapshot.val())) {
        console.log(`${key}: ${value.via_id}`);
        via.push(*** here build the Promise based on the key value ***)

        // example with Axios https://github.com/axios/axios
        via.push(axios.get('https://..../via?ID=' + key));
      }
      
      return Promise.all(via);
    })
    .then(results => {
      // results is an Array of results of each call to the API
      // For example
      results.forEach(r => {
        // ...
      })
    })
    .catch((error) => {
      console.error(error);
    });

推荐阅读