5

I want to fetch the required app version number when the app starts. But I can't get the right key.

I have this code to fetch. I use observe single event because I use this method to check the required app version number. This method is only fired when the app starts to do the check.

func getVersion(completionHandler: @escaping (Result<Any?>) -> ()) {

     let ref: DatabaseReference! = Database.database().reference().child("version").child("IOS")

     ref?.observeSingleEvent(of: .value , with: { snapshot in

         if snapshot.exists() {    
            let recent = snapshot.value as!  NSDictionary  
            print(recent)
         }
     })
}

But it is returning old results? I have isPersistenceEnabled enabled at my Appdelegate.

This is the database structure:

enter image description here

I get no results when I use Database.database().reference().child("version").child("IOS"). snapshot.exists is false when I use that.

What I previously had was: - version | IOS - 1.0

And i get result when I use Database.database().reference().child("version"), namely {iOS => 1.0}. I don't get it because it was my old structure.

Anurag Sharma
  • 4,276
  • 2
  • 28
  • 44
da1lbi3
  • 4,369
  • 6
  • 31
  • 65
  • 1
    When `isPersistenceEnabled` is set to true, observers fetch data from local storage first. Since `observeSingleEventOfType` is meant to observe only once, it'll only fetch data from local storage. – Muhammad Hassan Jul 28 '17 at 13:49
  • @MuhammadHassan Is there a way to force reload the data? – da1lbi3 Jul 28 '17 at 13:53

2 Answers2

1

The Firebase Realtime Database synchronizes and stores a local copy of the data for active listeners. In addition, you can keep specific locations in sync.

let scoresRef = Database.database().reference(withPath: "scores")
scoresRef.keepSynced(true)

The Firebase Realtime Database client automatically downloads the data at these locations and keeps it in sync even if the reference has no active listeners. You can turn synchronization back off with the following line of code.

scoresRef.keepSynced(false)

Haven't really tried it but it should work.

Muhammad Hassan
  • 1,037
  • 1
  • 8
  • 22
  • Does that mean you have a constant connection to Firebase while it's true? Just wondering coz you're only allowed 100 simultaneous connections on the free tier. @Muhammad Hassan – Jan-Dawid Roodt Nov 13 '18 at 06:08
  • Haven't gone through Firebase docs lately but user base on a free tier crossed 500 on one of the apps (I've worked on) with no complaints. – Muhammad Hassan Nov 13 '18 at 08:21
  • Oh wow, are you sure they were simultaneous connections? If you go to firebase -> Database -> Usage does it say 500 there or do you mean users? (Either way congrats! haha) – Jan-Dawid Roodt Nov 13 '18 at 22:28
1

The observeSingleEvent method is used for data that doesn't really change, and as such it will fetch from the local cache if you have persistence enabled.

This Android solution (https://stackoverflow.com/a/40477280/883413) provides a workaround by using an alternate method, runTransactonBlock.

Transactions give an opportunity to edit any data before they are saved. Here, we can simply accept the data as correct as we are only interested in reading the latest values.

let ref: DatabaseReference! = Database.database().reference().child("version").child("IOS")
ref.runTransactionBlock({ (data) -> TransactionResult in
    return TransactionResult.success(withValue: data)

}, andCompletionBlock: { (error, success, snapshot) in
    if let snapshot = snapshot, snapshot.exists() {
        if let recent = snapshot.value as? NSDictionary {
            print(recent)
        }
    }
})
Ric Santos
  • 15,419
  • 6
  • 50
  • 75