0

I have been using Firebase Database in my Android app for almost a year now and it works pretty nice. Unfortunately the data stops being synced to the could after some time. It is just never synced/stored to the cloud. Only local. So when user reinstalls the app, it only contains the data which was stored in the cloud. So to the user it looks like the data was removed, but actually is was never stored. I checked and the data is not visible in the firebase-console. Because it happens after a reinstall I guess it has something to do with the syncing. Users report losing data of about 2-3 months.

I'm using the following singleton helper class. Note I use the setPersistenceEnabled(true) and keepSynced(true).

public class FirebaseHelper{

    protected FirebaseHelper(Context c) {
        this.c = c.getApplicationContext();
        FirebaseDatabase.getInstance().setPersistenceEnabled(true);
        mAuth = FirebaseAuth.getInstance();
        this.userRef = FirebaseDatabase.getInstance().getReference().child(((BuildConfig.DEBUG ? "debug" : "release"))).child("users").child(getUID());
        this.userRef.keepSynced(true);
        this.path1 = userRef.child("path1");
        this.path2 = userRef.child("path2");
        this.path3 = userRef.child("path3");
        this.path4 = userRef.child("path4");
    }

    public static FirebaseHelper getInstance(Context c) {
        if (instance == null) {
            instance = new FirebaseHelper(c);
        }
        return instance;
    }


    public String insertObject(MyObject obj) {
        DatabaseReference newItem = this.path1.push();
        String pushID = newItem.getKey();
        obj.id = pushID;
        newItem.setValue(obj.getObject());

        return pushID;
    }

    public void updateData(...){}

    ...other methods

}

What could possibly be the cause of this?

Robin Dijkhof
  • 18,665
  • 11
  • 65
  • 116
  • please refer https://stackoverflow.com/questions/45271543/firebase-database-not-syncing-properly – Shalu T D Apr 10 '18 at 16:26
  • No that is not an answer. It does not take a few seconds, it just doesn't happen. Also the app is open now and then as the user adds data. – Robin Dijkhof Apr 10 '18 at 16:39
  • So you are saying data gets removed from the database after a user reinstalls? – André Kool Apr 11 '18 at 08:26
  • @AndréKool well it isn't removed. It is just never synced/stored to the cloud. Only local. So when user reinstalls the app, it only contains the data which was stored in the cloud. So to the user it looks like the data was removed, but actually is was never stored. – Robin Dijkhof Apr 11 '18 at 08:45
  • 1
    Wow that sounds like a huge problem if data isnt being stored for months. Does the user work offline all that time? Do you activly save data in your app? I think you should probably rewrite your question because the reinstall doesnt sound like the problem but the fact that data isnt being stored online. – André Kool Apr 11 '18 at 08:50
  • @AndréKool Indeed I think it is a huge problem. I'm pretty sure the user isn't offline for that long. – Robin Dijkhof Apr 11 '18 at 10:19
  • @AndréKool data is saved almost daily. – Robin Dijkhof Apr 11 '18 at 10:21
  • Can you add the actual code you use for reading and writing to firebase? Maybe you have a problem simular to [this one](https://stackoverflow.com/q/33260450/4916627) – André Kool Apr 11 '18 at 11:40
  • @AndréKool I added the insert, but it is not that special. Also that question you are refering is outdated. – Robin Dijkhof Apr 11 '18 at 17:43
  • I don't see anything in your code that implies saving to cloud... – Mars Apr 19 '18 at 04:30
  • @Mars that is what firebase should do. – Robin Dijkhof Apr 19 '18 at 09:40
  • Oops. If Ahamded Anees's answer isn't correct (1) is the most likely answer, depending on how you've implemented your getUID()), i think the next most likely answer is that your user had a copy of your app, if that's possible. Can you check the DB to see that the correct location was being written to? – Mars Apr 20 '18 at 00:56
  • @RobinDijkhof I've updated the answer once again. Please check it. – Bertram Gilfoyle Apr 20 '18 at 07:45

3 Answers3

2

There are only three reasons for this to happen to the best of my knowledge.

1) The method getUID()

Somehow the getUID() method is returning a null or invalid value which leads the data to be stored to somewhere else or it is not getting stored at all.

You are using simply getUid() instead of FirebaseAuth.getInstance().getCurrentUser().getUid(). So it must be a user defined method.

I think your getUid() does something like this.

String getUid() {
    try{
        return FirebaseAuth.getInstance().getCurrentUser().getUid() ;
    } catch (NullPointerException e) {
        return null;
    }
}

FirebaseAuth.getInstance().getCurrentUser() will return null if cache is cleared. It will lead your data to be lost.

2) Redundant data

Since Marshmallow, data is backed up to the cloud including shared preference. If you are checking shared preference to decide if user is logged in, user will be gone taken inside after reinstalling the app, skipping the login page. But actually he is not logged in which means FirebaseAuth.getInstance().getCurrentUser() returns null and any attempt to access the database will fail (depends on your database rules).

Solution: use FirebaseAuth.getInstance().getCurrentUser()==null to check if user is enabled. You can alternatively set backup to false. But I prefer first method.

3) An internal bug in Firebase SDK

Unfortunately there is nothing much we can do with it. Try narrowing it down and find a scenario by which the issue can be reproduced and report it to Firebase.


By the way, child(((BuildConfig.DEBUG ? "debug" : "release"))) is really smart. I am going to adopt it.

Bertram Gilfoyle
  • 9,899
  • 6
  • 42
  • 67
  • I store the uid in the shared preferences. Can't think of any way to reset the shared preferences without deleting other data. Right? – Robin Dijkhof Apr 20 '18 at 06:42
  • Yes. You are right. Please check the updated answer. – Bertram Gilfoyle Apr 20 '18 at 08:15
  • I'm confused. How would 1 or 2 result in local db writes but not cloud syncing? Wouldn't 1 or 2 result in an exception or crash? – Mars Apr 26 '18 at 00:44
  • If `getUid()` returned and invalid data, there will not be any crash but data will be stored somewhere else. However, you are right, it will crash due to a NPE otherwise. Scenario 2 wont crash the app but the write attempt will simply fail and print `Permission denied` to stacktrace. – Bertram Gilfoyle Apr 27 '18 at 05:00
0

Well, if your database has been syncing and you have not made any changes to the code whatsoever, it means that this is a firebase error, particularly related to the mobile phone the user is using.

Most developers who use firebase find problems querying the database when certain carriers are used. I have researched into this issue but i have not yet resolved it yet. If you happen to be using mobile data, actions like authenticating a user may not work.


Solution

Use a different internet source to test your code. Try using wifi instead of mobile data while debugging or testing your app.

if I find any helpful work around, I will file it on a firebase project experiencing the problem on open source Lucem

Lucem
  • 2,912
  • 3
  • 20
  • 33
  • Do you have any sources on the carirer part? – Robin Dijkhof Apr 19 '18 at 12:16
  • `Network error (such as timeout, interrupted connection or unreachable host) has occurred` this is the error that is thrown when you authenticate with mobile data. For queries, it does not show any error. `setPersistenceEnabled(true)` however allows the app to save the work on the users disk until the user is back online. The user however hasnt used a different carrier for the particular 2 months – Lucem Apr 19 '18 at 12:30
  • @RobinDijkhof this issue hasnt been resolved yet. take a look at this question https://stackoverflow.com/questions/45393413/firebase-android-app-not-working-with-mobile-data – Lucem Apr 19 '18 at 12:32
  • To validate my answer, try reauthenticating that user with the carrier or making a query then switch to a different network and you will see the difference. I have some apps too i face the sae problem. here [Ample Binary](https://play.google.com/store/apps/details?id=com.anb.lucem.anablucem) – Lucem Apr 19 '18 at 12:35
0

Throwing this out as a guess as well: At some point you distributed an app where BuildConfig.DEBUG = true, so users that install an updated version "lose" their data. Doesn't explain why other users haven't reported shorter losses though...

The solution would be a data migration, checking which has newer data and then copying the data if DEBUG is newer.

Mars
  • 2,505
  • 17
  • 26
  • He will get an error "You uploaded a debuggable APK. For security reasons you need to disable debugging before it can be published in Google Play" while uploading a debug build if he is using play store to distribute his application – Bertram Gilfoyle Apr 20 '18 at 04:25
  • If its published on Google Play. Could be enterprise or private use – Mars Apr 20 '18 at 04:33