Firebase-ios-sdk: Incorrect long values storage in database persistent storage

Created on 3 Oct 2017  路  16Comments  路  Source: firebase/firebase-ios-sdk

  • Xcode version: 9.0 (9A235)
  • Firebase SDK version: 4.2.0
  • Library version: 4.2.0
  • Firebase Product: database

Hello, we store dates in firebase like long numbers in milliseconds since the epoch.
All works fine, until I enable database data persistence on disk

It looks like, SDK stores long values as ints and int overflow happens.

When I download value like 1506428988000 from database - all works fine, but, when I fetch same value from local cache - it returns -1104532896

database

Most helpful comment

Guys, any progress on this issue?

All 16 comments

Guys, any progress on this issue?

I also have this issue. As far as I know this only occurs when running on 32bit iPhones.

We have disabled persistence on 32 bit device for now.

Sorry, we have been unable to reproduce this by building for 32 bit architecture. The latest 32 bit device that Apple produced was a 5C. I will see if we can get our hands on one.

Yes, we have seen this issue surface with the iPhone 5C. When persistence is enabled this does not occur the first time, because there is no local instance of the data yet. But when we force close the app, restart, and retrieve the data (which then comes from the persistent storage) we get a 32 bit integer instead of the expected long value

Yes, I have this issue with an iPad 4th generation. Same thing: Disconnecting the device from the internet will always return wrong timestamps.

facing the same issue. we too are storing timestamps in millis. this problem only occurs if the data from cache is returned.

I've contacted Firebase support about this and they asked for a way to reproduce the issue. I thought I may as well post it here as well.

func runOnFirstOpen() {
    Database.database().isPersistenceEnabled = true
    let ref = Database.database().reference(withPath: "start")
    ref.setValue(1506428988000)
}

// Now force close the app, turn on airplane mode, and open the app

func runOnSecondOpen() {
    Database.database().isPersistenceEnabled = true
    let ref = Database.database().reference(withPath: "start")
    ref.observe(.value) { (snapshot) in
        let start = snapshot.value as? Int64

        // "start" should be 1506428988000 but it is -1104532896

        // If you now turn off airplane mode another value event is received
        // with the correct value of 1506428988000
    }
}

Edit: Replaced "keepSynced" with "setPersistenceEnabled" to correctly repro the issue.

For now, I would suggest working around this issue by storing large numbers as Strings.

@chetbox If you have time, it would be interesting to know is this still reproduced with the code in https://github.com/firebase/firebase-ios-sdk/blob/f08b5044d64197a3227017ad44235a2bd7421691/Firebase/Database/Persistence/FLevelDBStorageEngine.m#L675 disabled. We will try to replicate this on a 32-bit device.

We have a lot of data (tens of gigabytes) already in our database and it's not practical to convert all our millisecond to a string and handle the change gracefully across Android, iOS and web clients.

I got my hands on an iPhone 5C - trying to reproduce now and will report back!

Confirmed, commenting out the code in fixDoubleParsing: works as per @schmidt-sebastian's suggestion. He's looking into a fix now and we're going to work together to get this fixed!

Thanks @ryanwilson and @schmidt-sebastian! 馃檹

The fix has landed! I'll make a comment when it's shipped (unfortunately the next release has already been assembled so it'll have to make it into the next one after that, ~2 weeks from now).

@ryanwilson we don't have any docs around this, but we've been keeping issues open until the releases they're in ship in the hopes that it'll prevent a small amount of duplicate issues.

Sorry about that! Will close it once it ships 馃憤

This fix is now published in Firebase 4.10.0.

Was this page helpful?
0 / 5 - 0 ratings