In Firebase, how can I query the most recent 10 child nodes?

前端 未结 3 846
醉话见心
醉话见心 2020-11-28 14:47

I\'m using childByAutoId() to generate my children. Each child looks like:

{
    user_id: 1
}

I\'d like to get the last 10 mos

相关标签:
3条回答
  • 2020-11-28 15:21

    The answer is that you need to use a bit of reverse logic, and also store a timestamp key:value pair within each node as a negative value. I omitted the user_id: 1 to keep the answer cleaner.

    Here's the Firebase structure

    "test" : {
        "-KFUR91fso4dEKnm3RIF" : {
          "timestamp" : -1.46081635550362E12
        },
        "-KFUR9YH5QSCTRWEzZLr" : {
          "timestamp" : -1.460816357590991E12
        },
        "-KFURA4H60DbQ1MbrFC1" : {
          "timestamp" : -1.460816359767055E12
        },
        "-KFURAh15i-sWD47RFka" : {
          "timestamp" : -1.460816362311195E12
        },
        "-KFURBHuE7Z5ZvkY9mlS" : {
          "timestamp" : -1.460816364735218E12
        }
      }
    

    and here's how that's written out to Firebase; I just used a IBAction for a button to write out a few nodes:

    let testRef = self.myRootRef.childByAppendingPath("test")
    
    let keyRef = testRef.childByAutoId()
    
    let nodeRef = keyRef.childByAppendingPath("timestamp")
    
    let t1 = Timestamp
    
    nodeRef.setValue( 0 - t1) //note the negative value
    

    and the code to read it in

        let ref = self.myRootRef.childByAppendingPath("test")
        ref.queryOrderedByChild("timestamp").queryLimitedToFirst(3).observeEventType(.ChildAdded, withBlock: { snapshot in
            print("The key: \(snapshot.key)") //the key
        })
    

    and I declared a little function to return the current Timestamp

    var Timestamp: NSTimeInterval {
        return NSDate().timeIntervalSince1970 * 1000
    }
    

    and the output

    The key: -KFURBHuE7Z5ZvkY9mlS
    The key: -KFURAh15i-sWD47RFka
    The key: -KFURA4H60DbQ1MbrFC1
    

    As you can see, they are in reverse order.

    Things to note:

    1. Writing out your timestamp as negative values
    2. When reading in use .queryLimitedToFirst instead of last.

    On that note, you can also just read the data as usual and add it to an Array then then sort the array descending. That puts more effort on the client and if you have 10,000 nodes may not be a good solution.

    0 讨论(0)
  • 2020-11-28 15:32

    I'm assuming your data actually looks like this:

    someDataSet: {
        longUID-1: {
            timeCreated: 9999999999, // (seconds since the javascript epoch)
            user_id: 1
        },
        longUID-2: {
            timeCreated: 1111111111,
            user_id: 2
        },
        longUID-3: {
            timeCreated: 3141592653,
            user_id: 3
        }
    }
    

    You could automate that by calling Firebase.push({user_id: ###, timeCreated: ###}) multiple times in a for loop or any other method. Maybe you're adding news stories to a webpage, but you only want your user to see the most current stories--- IDK. But the answer to your question is to use Firebase's ref.orderByChild() and ref.limitToLast().

    var ref = new Firebase("<YOUR-FIREBASE-URL>.firebaseio.com/someDataSet"); 
        //the "/someDataSet" comes from the arbitrary name that I used up above
    
    var sortedRef = ref.orderByChild('timeCreated');
        //sort them by timeCreated, ascending
    
    sortedRef.limitToLast(2).on("child_added", function(snapshot){
        var data = snapshot.val();
    
        console.log(data);
    
        /* do something else with the data */
    });
    
    //The console would look like this
    
    // Object {timeCreated: 9999999999, user_id: 1}
    // Object {timeCreated: 3141592653, user_id: 3}
    

    This happened because the program took the child with the greatest timeCreated value first and then the second greatest (value) second... Also note, the longUID means nothing when you sort them by child and neither do the other values (user_id in this case)

    Here is the documentation for:

    • Firebase .push() method (Sorry, I'm not allowed to post this link- I dont have enough reputation)
    • Firebase .orderByChild method
    • And also, Firebase .limitToLast method
    0 讨论(0)
  • The code: ref.queryOrderedByKey().queryLimitedToLast(10) can be used for getting the most recent 10 data. However, this is an ascending order by default.

    Alternatively, you can order your data via

    ref.orderByChild("id").on("child_added", function(snapshot) {
      console.log(snapshot.key());
    });
    

    This also presents an ascending order by default. To change it into descending order is little bit tricky. What I would suggest it to multiply ids by -1 as shown below and then sort them.

    var ref= new Firebase("your data");
    ref.once("value", function(allDataSnapshot) {
      allDataSnapshot.forEach(function(dataSnapshot) {
        var updatedkey = -1 * dataSnapshot.key();
        ref.update({ element: { id: updatedkey}});
      });
    });
    

    This two SO page might be useful for you also, please check:

    How to delete all but most recent X children in a Firebase node?

    firebaseArray descending order?

    0 讨论(0)
提交回复
热议问题