Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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().

like image 242
lf215 Avatar asked Nov 09 '22 07:11

lf215


1 Answers

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

like image 59
Dravidian Avatar answered Nov 14 '22 23:11

Dravidian