Search code examples
swiftfirebaseobservers

How can I retrieve the data once in Firebase 3 and Swift 3 (Stopping observer)


I started my web application in angularjs 1.5 with firebase 3. I want now create an IOS App for my Web App. The application is a clocksystem where the user are able to checkin or checkout his worked time.

To make this simple, I've like this table in firebase:

worktimes
   -Kd4swkAQJTRjCbD0CCy
     + ----- IN  | '2017-02-16 10:00:00'
     + ----- OUT | '2017-02-16 13:00:00'

Cases:

  • If the User has an "OUT" value, create a new worktime.
  • If the user hasn't a value in "OUT", like NULL, I want to update "OUT" and set the current timestamp.

In JS, my code looks like this:

var database = firebase.database();
var ref = database.ref().child('worktimes')

Query (Javascript):

ref
   .startAt('2017-02-16 00:00:00')
   .endAt('2017-02-16 23:59:59')
   .orderByChild('timestamp')
   .limitToLast(1)
   .once('value', function(snapshot) { 
       // Getting data once here
})

Query (Swift 3):

ref
   .queryStarting(atValue: "2017-02-16 00:00:00")
   .queryEnding(atValue: "2017-02-16 23:59:59")
   .queryOrdered(byChild: "timestamp")
   .queryLimited(toLast: 1) // return only the latest entry
   .observe(FIRDataEventType.value, with: { (snapshot) in

      if !snapshot.value is NSNull {
         // work here with the data once

        for child in snapshot.children {
        // if I do an update here like this:

              let snap = child as! FIRDataSnapshot 
              let dict = snap.value as! [String: AnyObject] 

              let id = dict["id"] as! String
              let IN = dict["in"]
              let OUT = dict["out"]

              if(OUT  == nil){

        // UPDATE QUERY     
        // If I update here my Data, the query ends and starts again.

        ref.child("-Kd4swkAQJTRjCbD0CCy").updateChildValues(["timestamp" : "2017-02-"])

              } else {

           // creating new worktime here.. 
           }

         } // end of for

      } // end of if

   })

As I wrote in the comment (see after update query), the snap ends finally, but It loops again through the snapshot. I've figured its because the data has changed it triggers the loop again.

I've tried with

ref.removeAllObservers()

To remove the observer. It worked fine, but If I tried after the update Query it doesn't worked. It creates a never stopping loop. How can I stop the observing, I don't need to check for new updates.

Thanks in advance!


Solution

  • Just use observeSingleEvent as outlined in the documentation

    ref
       .queryStarting(atValue: "2017-02-16 00:00:00")
       .queryEnding(atValue: "2017-02-16 23:59:59")
       .queryOrdered(byChild: "timestamp")
       .queryLimited(toLast: 1) // return only the latest entry
       .observeSingleEvent(of: FIRDataEventType.value, with: { (snapshot) in
           ...