首页 文章

orderByChild无法在Firebase中运行

提问于
浏览
23

我正在尝试查询我的数据库,以便它根据子键检索有序列表 . 我这样做(见下文),但没有任何反应,这意味着它返回一个完全按照存储在Firebase数据库中的方式排序的对象 . 到底是怎么回事?

self.getAllProfiles = function () {
    var qProfile = $q.defer();
    var ref = new Firebase(FBURL);
    ref.child("users").orderByChild('last_update').on("value", function (snapshot) {
        console.log(snapshot.val()) // HERE IS WHERE IT SHOULD BE ORDERED
        qProfile.resolve(snapshot.val());
    }, function (errorObject) {
        qProfile.reject(errorObject);
    });
    return qProfile.promise;
};

要添加,我的用户节点如下所示:

users
   /$username
       /last_update
       /id
       /data
          /profile_image
          /display_name

这是一个快照:

Tester: Object
   github: Object
   last_update: 1447732462170
   userId: "github:12345"

4 回答

  • 69

    当您调用 snapshot.val() 时,您将返回一个JSON对象 . JSON对象中的键顺序由浏览器决定,而不是由Firebase决定 .

    为了让孩子们顺序:

    self.getAllProfiles = function () {
        var qProfile = $q.defer();
        var ref = new Firebase(FBURL);
        ref.child("users").orderByChild('last_update').on("value", function (snapshot) {
            snapshot.forEach(function(child) {
                console.log(child.val()) // NOW THE CHILDREN PRINT IN ORDER
            });
            qProfile.resolve(snapshot.val());
        }, function (errorObject) {
            qProfile.reject(errorObject);
        });
        return qProfile.promise;
    };
    

    您可以将 q.resolve() 调用保留在原来的位置: snapshot.forEach() 不是异步调用 .

  • 0

    我知道这个问题已经回答并且已经超过1年了,但由于评论部分仍有一些混淆,我想补充一些信息 .

    问题

    最初的问题是OP想要根据Firebase实时数据库中的子键检索有序列表,但 .orderByChild('arg') 无法按预期工作 .

    但是没有按预期工作的不是 .orderByChild('arg') ,而是 .on("value", callback) . 因为 .on("value", callback).on("child_added", callback) 等其他eventType有点不同 .

    示例

    假设我们有一个firebase实时数据库,如下所示:

    {
        myData: {
            -KYNMmYHrzLcL-OVGiTU: {
                 NO: 1,
                 image: ...
            },
            -KYNMwNIz4ObdKJ7AGAL: {
                 NO: 2,
                 image: ...
            },
            -KYNNEDkLpuwqQHSEGhw: {
                 NO: 3,
                 image: ...
            },
        }
    }
    

    如果我们使用 .on("value", callback) ,则回调()将被调用1次,并返回3个对象的对象数组 .

    ref.on("value", function(snapshot) {
        console.log(snapshot.val());
        // Please see Frank van Puffelen's answer
    }
    

    enter image description here

    如果我们使用 .on("child_added", callback) ,则回调()将被调用3次,每次返回一个Object,并返回 in order .

    ref.once("child_added", function(snapshot) { 
        console.log(snapshot.val());
        // The objects are returned in order, do whatever you like
    }
    

    enter image description here

    结论

    如果你只需要从firebase获取有序数据(例如初始化UI) . 那么 ref.orderByChild('arg').once("child_added", callback) 很适合你,它简单易用 .

    但是,如果由于某种原因你需要使用 ref.orderByChild('arg').on("value", callback) ,请参阅Frank van Puffelen的回答 .

    参考

    有关 on(eventType, callback, cancelCallbackOrContext, context) ,其参数及其返回值的更多信息,请阅读Firebase Document .

    另一个有用的文件:Work with Lists of Data on the Web

  • 13

    要使用 value 事件侦听器进行排序:

    firebase.database().ref('/invoices').orderByChild('name').on('value', snapshot => {
        snapshot.forEach(child => {
            console.log(child.key, child.val());
        });
    }
    

    如果要撤销订单,请尝试:

    function reverseSnapshotOrder (snapshot) {
      let reversed = [];
    
      snapshot.forEach(child => {
        reversed.unshift(child);
      });
    
      return reversed;
    }
    
    reverseSnapshotOrder(snapshot).forEach(child => {
      console.log(child.key, child.val());
    });
    

    请参阅:https://firebase.google.com/docs/database/web/lists-of-data#listen_for_value_events

  • 1

    我在iOS中遇到同样的问题 . 如果将快照转换为NSDictionary对象,则会转换为无序列表 . Objective-c版本,如有需要:

    [[self.refChild queryOrderedByChild:@"date_created"] 
      observeEventType:FIRDataEventTypeValue 
             withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {
    
         for (FIRDataSnapshot *child in snapshot.children) {  
    
              NSDictionary *anObject = child.value; 
              NSString *aKey         = child.key;      
         } 
    }];
    

相关问题