【问题标题】:Firebase: How to run a callback after all the initial "child_added" calls?Firebase:如何在所有初始“child_added”调用后运行回调?
【发布时间】:2016-06-14 09:53:27
【问题描述】:

当监听“child_added”事件时:

ref.on("child_added", function (snapshot) {

});

此回调函数最初将为引用中存在的每个子项运行一次。

该位置的每个初始孩子都会触发一次此事件,每次添加新孩子时都会再次触发。

https://firebase.google.com/docs/reference/node/firebase.database.Reference

我想利用这个事实和排序函数来构造一个有序数组:

orderedArray = [];

ref.orderByValue("rating").on("child_added", function (snapshot) {
    orderedArray.push(snapshot.val())
});

// how do I run a callback after the last child has been added?

但是,没有办法(据我所知)知道上次调用 child_added 回调的时间,因此在将最后一个子元素添加到我的数组后,我无法准确地运行我自己的回调。


这是我现在的解决方法:

orderedArray = [];

ref.orderByValue("rating").on("child_added", function (snapshot) {
    orderedArray.push(snapshot.val())
});

setTimeout(function() {

    ref.off("child_added") // unbind event
    callback()

}, 3000)

这很粗略,尤其是在从数据库中获取所有数据需要 3 秒以上的情况下。

这里有什么想法吗?

【问题讨论】:

    标签: javascript firebase firebase-realtime-database


    【解决方案1】:

    您可以使用DataSnapshot.forEach 遍历父快照并将子快照排序到数组中:

    const ref = firebase.database().ref().child('items');
    const items = [];
    ref.once('value', snap => {
      snap.forEach(item => { items.push(item) });
      console.log(items);
    });
    

    由于您调用ref.off() 来读取一次数据,因此使用.once() 方法并迭代父快照是有意义的。

    【讨论】:

    • forEach() 会按顺序读取它们,即使我使用了像 orderByValue() 这样的排序功能?
    • snap中有大量项目怎么办?听起来这个解决方案首先将所有项目加载到内存中,然后将它们提供给回调。
    • 你是如何做到的,以便在添加新状态时将其保存在数组中?这是我在使用child_added 时看到的意图还是此方法仅用于报告?
    【解决方案2】:

    我尝试做的是使用observeSingleEvent 监听器。

    // Following a Swift code but the logic remains same.
    Database.database()
    .reference(withPath: "The_Path")
    .observeSingleEvent(of: .value) { (snapshot) in
        // Iterate and save the values from the snapshot.
        // Now initiate `childAdded` and `childChanged` listeners.
        self.keepObserving()
    }
    

    完成后添加childAddedchildChanged

    func keepObserving() {
        Database.database()
        .reference(withPath: "The_Path")
        .observe(.childAdded) { (snapshot) in
            // Check if the value in the snapshot exists in the your array or data model.
            // If not then add it to your container else return.
        }
    
        Database.database()
        .reference(withPath: "The_Path")
        .observe(.childChanged) { (snapshot) in
            // Find the indexOf the data in snapshot in array or container.
            // If the index is found or exist replace the changed value.
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-10-15
      • 2020-09-05
      • 1970-01-01
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-04
      相关资源
      最近更新 更多