0

I tried googling this problem but it seems like everyone has the opposite problem where the app runs on simulator but not their device. I've been struggling a LOT all week with firebase asynchronous calls returning null and linked the issue to persistence being enabled. All my problems go away if I disable persistence, but I want it enabled. I learned recently about synchronous issues with the different listeners/persistence and have been struggling with firebase returning outdated/nil values for a while.

Simulator was working just a week or two ago and I'm not sure what's changed. I've tried messing with / switching out .observeSingleEvent for .observe and still crashes at this code:

let synced = ref.child("profiles").child((FIRAuth.auth()?.currentUser?.uid)!).child("level")

synced.observeSingleEvent(of: FIRDataEventType.value, with: { (snapshot) in

    print(snapshot)
    print(snapshot.ref)

    if (snapshot.value as! String == "One") {
     ........//CRASH

With the message:

Could not cast value of type 'NSNull' (0x10b7cf8c8) to 'NSString' (0x10a9dfc40).

When I try to print snapshot, it shows me an empty snapshot. But when I print the ref, the link works and takes me to the right place in my db (where I can see the data exists)

Any ideas how to fix/get around this without disabling persistence? Or more importantly I guess, should I care that it doesn't work in simulator if it works on a device? Will this matter for app store approval / affect future users?

If you'd like to see for yourself that this is an issue of firebase getting a nil/outdated value when the reference exists, here is what I see when I follow the printed ref link enter image description here

Alex
  • 299
  • 3
  • 16

1 Answers1

1

The error seems fairly explicit: there is no value, so you can't convert it to a string.

synced.observeSingleEvent(of: FIRDataEventType.value, with: { (snapshot) in
    if (snapshot.exists()) {
        if (snapshot.value as! String == "One") {
         ........//CRASH
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • No, what I mean is that the value is a string, there IS a value, and I can see it in my database. I am positive that it is pointing to the right place in my databse and contains a string value. The problem is that firebase thinks that snapshot is nil. This is something to do with listeners/persistence, explained in this post: – Alex Feb 25 '17 at 05:03
  • If you're not getting the value you expect, it most likely has the location cached (on disk or in memory) as nil. Your code will need to deal with that. I've said a few times this week already: using disk persistence and single value event listeners/observers don't mix. For a longer explanation, see http://stackoverflow.com/questions/34486417/firebase-offline-capabilities-and-addlistenerforsinglevalueevent/34487195#34487195 – Frank van Puffelen Feb 25 '17 at 05:06
  • Thank you, I did see the explanation, however when I switch this call to '.observe(FIRDataEventType.value)' instead of single, the crash still happens. I also tried adding a call to synced.keepSynched(true) with no luck. I tried putting the call to synced.keepSynched(true) before I attach the listener and within the listener. Am I missing something else? Thank you again for the help, it is very appreciated. – Alex Feb 25 '17 at 05:08
  • There is still a `nil` in the cache. See the snippet of code I shared to handle that correctly. – Frank van Puffelen Feb 25 '17 at 16:47