0

I am trying to do a simple ordered query request based on epoch timestamps:

guard let user = Auth.auth().currentUser?.uid else {return}
let queryRef = Database.database().reference().child("ordersBackup").child(user).queryOrdered(byChild: "pickupCompleteAfter").queryLimited(toFirst: 1)
queryRef.observeSingleEvent(of: .childAdded, with: { (snapshot) in
    print(snapshot.value)
})

Structure:

{
  "UserId" : {
    "UniqueId1" : {
      "pickupCompleteAfter" : 1568314979000,
      "name" : "Jeff"
    },
    "UniqueId2" : {
      "pickupCompleteAfter" : 1557687779000,
      "name" : "Stig"
    },
    "UniqueId3" : {
      "pickupCompleteAfter" : "1578855779000",
      "name" : "Ali"
    }
  }
}

It should return UniqueId2. However, I am always retrieving the same order as the structure i.e UniqueId1, UniqueId2, UniqueId3. It doesn't take the timestamp into consideration at all. What am I doing wrong?

Output:

LQ8nHi
{
    orderInfo =     {
        deliveryCompleteAfter = 1552917600000;
        deliveryCompleteBefore = 1552924800000;
        pickupCompleteAfter = 156249280000;
        pickupCompleteBefore = 1552492800000;
    };
}
YQxeKv
{
    orderInfo =     {
        deliveryCompleteAfter = 1552917600000;
        deliveryCompleteBefore = 1552924800000;
        pickupCompleteAfter = 1557687779000;
        pickupCompleteBefore = 1552492800000;
    };
}
ibIPO9
{
    orderInfo =     {
        deliveryCompleteAfter = 1553090400000;
        deliveryCompleteBefore = 1553097600000;
        pickupCompleteAfter = 1578855779000;
        pickupCompleteBefore = 1552665600000;
    };
}

enter image description here

chetbaker
  • 23
  • 8
  • If you get the value of a `DataSnapshot`, you're losing all information about the order of the data in that value. To maintain the order information, you need to loop over `snapshot.children` as shown here https://stackoverflow.com/questions/27341888/iterate-over-snapshot-children-in-firebase and https://stackoverflow.com/questions/41307826/searching-through-child-values-firebase-swift. – Frank van Puffelen Mar 12 '19 at 21:19
  • Thanks for answering, but I don't really follow. .queryLimited(toFirst: 1) only returns one child (as snapshot), so makes no sense to loop over snapshot.children. I also tried to do that with same results. – chetbaker Mar 12 '19 at 21:32
  • When you execute a query against the Firebase Database, there will potentially be multiple results. So the snapshot contains a list of those results. Even if there is only a single result, the snapshot will contain a list of one result. Ah, I now see that you're observing `.childAdded`, which makes a difference. – Frank van Puffelen Mar 12 '19 at 21:34
  • Can you edit your question to show the output from the `print` statement? – Frank van Puffelen Mar 12 '19 at 21:37
  • I am sorry for being vague, basically I just want the highest value or the lowest value. But it always returns the value of the first node in the firebase hierarchy (UniqueId1). If I use .queryLimited(toLast: 1), i'm getting the last node. I never get the node with the highest value on pickupCompleteAfter, it doesn't take that into consideration at all. – chetbaker Mar 12 '19 at 21:50
  • Maybe get rid of the .queryLimited, and then does it return the full list in order regards to `"pickupCompleteAfter"`? – Peter Ruppert Mar 12 '19 at 22:21
  • removing queryLimited gives me the exact same order as firebase (LQ8nHi, YQxeKv, ibIPO9). No consideration to pickupCompleteAfter given. So weird.. – chetbaker Mar 12 '19 at 22:33
  • I also tried to query on range without any success.. also tried to query for the other timestamps, but still giving me the exact same order. I can write anything in queryOrdered(byChild: "") and it gives me the exact same order, doesn't matter.. – chetbaker Mar 12 '19 at 22:35
  • Keep in mind that we have no idea how to interpret your data structure, unless you tell us. I see `Database.database().reference().child("ordersBackup").child(user)` as the base of the query, but can't know what that maps to. But if it maps the to level of `ryxt...` in your database, then you're trying to order/filter on a nested property. I'll answer for that, but in general: please spend the time to isolate the problem, as shown in [how to create a minimal, complete, verifiable example](http://stackoverflow.com/help/mcve). – Frank van Puffelen Mar 13 '19 at 01:12

1 Answers1

0

The pickupCompleteAfter is nested under the orderInfo node of each child. You're current not telling the database about that full path, so it only checks for a pickupCompleteAfter right under each child.

To order/filter on orderInfo/pickupCompleteAfter, use:

let query = Database.database().reference().child("ordersBackup").child(user)
  .queryOrdered(byChild: "orderInfo/pickupCompleteAfter").queryLimited(toFirst: 1)
query.observeSingleEvent(of: .childAdded, with: { (snapshot) in
    print(snapshot.value)
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Same problem.. The only child node thats not included in the query is the autoIds, are they causing the problem perhaps? `Lq8nHi, YQxeKv, iblPO9` – chetbaker Mar 13 '19 at 09:05