lf215 lf215 - 1 month ago 16
iOS Question

iOS Firebase sort and limit - observer not called

This is my data model.

project-foo
-posts
-KLs123412341234
key: "-KLs123412341234"
message: "free cupcakes"
time: 1467675688163
-...
key: "..."
message: "..."
time: ...


I'd like to only fetch posts in the last 15 minutes.
I see in my Firebase Console children being added, but the problem is that the observer doesn't seem to be invoked -
"hello"
is not printed.

My iOS app has the following code, which does not get invoked:

class ViewController: UIViewController {

var ref: FIRDatabaseReference?

override func viewDidLoad() {
super.viewDidLoad()

ref = FIRDatabase.database().reference()
ref!.queryOrderedByChild("time")
.queryStartingAtValue(startTime())
.observeEventType(.ChildAdded, withBlock: { snapshot in
print("hello")
})

}
}


My Android app has the following code, which does get invoked:

Query query = mDatabase.orderByChild("time").startAt((double)startTime());
query.addChildEventListener(new PostListener(this, mMap));

class PostListener implements ChildEventListener {
public PostListener(Context context, GoogleMap map) {
...
}

@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Log.i(TAG, "hello");
...
}
}


Update:
My mistake was not realizing that I had initialized
mDatabase
(in the android version) with path
posts
. The fix was simply to initialize
ref
with
FIRDatabase.database().referenceWithPath("posts")
instead of
FIRDatabase.database().reference()
.

Answer

For JSON structure,:-

"posts" : {
  "autoID1" : {
    "key" : "autoID1",
    "timestamp" : 101
  },
  "autoID2" : {
    "key" : "autoID2",
    "timestamp" : 102
  },
  "autoID3" : {
    "key" : "autoID3",
    "timestamp" : 103
  },
  "autoID4" : {
    "key" : "autoID4",
    "timestamp" : 104
  },
  "autoID5" : {
    "key" : "autoID5",
    "timestamp" : 105
  },
  "autoID6" : {
    "key" : "autoID6",
    "timestamp" : 106
  },
  "autoID7" : {
    "key" : "autoID7",
    "timestamp" : 107
  }
}

Use this code:-

  FIRDatabase.database().reference().child("posts").queryOrderedByChild( "timestamp").queryStartingAtValue(101).queryEndingAtValue(103).observeEvenType(.Value, with: { (snap) in
        if let snapDict = snap.value as? [String:AnyObject]{

            for each in snapDict{

                print(each.value)

            }
          }
        }, withCancel: {(err) in


    })

Make sure your security rules are allowing the user to retrieve posts value's

Using .ChildAdded only gets called when a child node is added to that Database node. Using .Value will retrieve you entire Data whose timestamp is between those value's

Now most likely you cannot get the Timestamp value from FIRServerValue.timestamp() as it's just a command sent to the firebase server to add the timestamp at that particular node.

So instead use a custom timestamp to store your timestamp, and for the end value just add 15 min to that timestamp.

Read this Manipulate NSDate

Comments