37
  1. Is there any way to clear data stored in Firebase Database persistence enabled via setPersistenceEnabled(true)?
  2. Or eventually prevent read access to previously stored users data on the device?
  3. And extra question - is there any way to check if any data is waiting to sync?

In my app I want to clear db when user is logging out and he confirm that unsynchronized changes will be removed. This app will be used on tablet by many people, and there'll be many data stored per user, so I want to clear unnecessary data stored on the device to:

  • shrink storage usage
  • prevent unauthorized person from read users data

It's a security flaw because any user, regardless of whether is signed in or not, has read access to all previously downloaded data! Fortunately we haven't write access there.

I tried to clear db on my own, in both offline and online mode, but data still persist on the device:

// first clear all data on my own
FirebaseDatabase db = FirebaseDatabase.getInstance();
db.goOffline(); // even when I clear db in online mode data persist on mobile device
db.getReference().setValue(null);

// and then logout
FirebaseAuth.getInstance().signOut();
db.goOnline();

eg data structure:

{
  "someList": {
    "userId1": {
      "itemId11": {
        "name": "name 11"
      },
      "itemId12": {
        "name": "name 12"
      },
      ...
      "itemId1N": {
        "name": "name 1N"
      }
    }
    "userId2": {
      "itemId21": {
        "name": "name 21"
      },
      "itemId22": {
        "name": "name 22"
      },
      ...
      "itemId2N": {
        "name": "name 2N"
      }
    }
  }
}

my rules:

{
  "rules": {
    ".read": "false",
    ".write": "false",
    "someList": {
      "$uid": {
        ".read": "$uid === auth.uid",
        ".write": "$uid === auth.uid"
      }
    }
  }
}
wrozwad
  • 2,610
  • 1
  • 30
  • 38
  • have u tried `mRef.keepSynced(false);` – Sahaj Rana Jul 09 '16 at 12:50
  • @SahajRana unfortunatelly adding `keepSynced(false)` in any place doesn't change anything. Only when I delete last `db.goOnline()` then I really can't read previous user data. But I can write and read new data as "logged out" user. And after logged in when I call `db.goOnline()` (to have db in sync) it clears all my old data on backend and at the same tame adds new data added as "logged out" user. – wrozwad Jul 09 '16 at 17:02
  • Actually when u set `setPersistenceEnabled(true)` firebase stores the data in cache form on your device so that it could show data when you are offline – Sahaj Rana Jul 09 '16 at 17:05
  • could u show more code of what u are trying to do.. and What exactly u want not to happen.. – Sahaj Rana Jul 09 '16 at 17:07
  • `setPersistenceEnabled(true)` also backStack your requests performed while you are offline and performs them next time you come online – Sahaj Rana Jul 09 '16 at 17:12
  • @SahajRana I know how Firebase persistence work. I just need to clear db (remove all pending operations) when user is logging out. Even with the possibility of losing unsynced changes. – wrozwad Jul 10 '16 at 09:39
  • by db u mean firebase database.. if so.. try to call `db.getReference().setValue(null);` before `db.offline()` – Sahaj Rana Jul 10 '16 at 09:41
  • @SahajRana Thx for try but I really tried this and 100 other combinations with `getReference().setValue(null)` – wrozwad Jul 10 '16 at 16:05
  • Did you find a solution to this? – marson May 13 '17 at 12:50
  • @marson Unfortunately I don't hear anything from Firebase team – wrozwad May 13 '17 at 16:35
  • 1
    This is definitely a security flaw and a massive usability flaw. It is causing me no end of chaos, surely there must be some way to manually remove this. It's even worse... after I delete the app entirely (macOS) then reinstall, the persistence cache still remains, and forces updates from that old cache to the server! This is crazy – Dan Horton Jul 18 '21 at 11:45

4 Answers4

12

Unfortunately there's no supported way to clear the persistence cache. You could try to manually delete the SQLite database used by Firebase Database (should be under /databases/ in your app's data folder), but you'd need to do it before initializing Firebase Database, so you'd have to force the app to restart after signing somebody out or similar.

Regarding knowing if there's "data waiting to sync", assuming you're talking about writes, the only way is to attach CompletionListeners to every write operation you do, and wait for them to complete.

Both of these are things we'd like to improve in future versions of the Firebase Database SDK.

Michael Lehenbauer
  • 16,229
  • 1
  • 57
  • 59
  • @Michael Legenbauer - So... is there any progress with it? – wrozwad Mar 03 '17 at 08:02
  • 6
    @michael-lehenbauer Any new progress on this? Due to firebase limitations of losing pending changes when app is terminated while offline, I'm seeing the local cache get out of sync with the database with no apparent way to resolve it. A way to clear the cache would be a good fallback. – Greg Ennis Jun 19 '17 at 17:39
  • you could use keepSync(true) – Abhilash Das Nov 17 '17 at 06:38
  • I also thought this would be a good approach, however the problem is even worse. After I delete the app entirely (macOS), do a full clean and rebuild, then reinstall, and the old persistence cache still remains! How on earth is this possible, where is it storing the cache, any ideas? – Dan Horton Jul 18 '21 at 11:47
3
    if (Build.VERSION_CODES.KITKAT <= Build.VERSION.SDK_INT) {
        ((ActivityManager) getContext().getSystemService(ACTIVITY_SERVICE))
                .clearApplicationUserData();
    }

source

Bradley Wilson
  • 1,197
  • 1
  • 13
  • 26
3

clearPersistence() was launched in v6.2.0.

via

https://github.com/firebase/firebase-js-sdk/issues/449

Jimmy Kane
  • 16,223
  • 11
  • 86
  • 117
  • Can you use `clearPersistence` during logout though? I've tried in a couple of ways, but can't stop the app. The `terminate` from Android SDK is not yet in the JS SDK it seems. I need to stop the app in order to be allowed to perform `clearPersistence`. – Simon B. Sep 25 '19 at 07:14
  • 3
    there are a few caveats that should be explained in this answer - check the docs: https://firebase.google.com/docs/reference/android/com/google/firebase/firestore/FirebaseFirestore#clearPersistence() After consideration the best advice i have read is not to use persistence if you need to clear the cache. – wal Feb 28 '20 at 05:18
  • the question was about realtime database not firestore – Apoleo Mar 11 '21 at 15:53
0

Oh dear what a terrible hack this solution is, I apologise in advance...

This works tho, to clear the local cache:

  • disable persistence

  • take a full copy of the new node, e.g. for user 2

e.g. var copyData = await (await ref.once()).value;

  • enable persistence

  • replace the new node, e.g. user 2, with the copyData

In theory only data which has been changed will be written, which should mean no changes to the realtime database. Meanwhile the local cache is replaced with the data from the server.

I got this approach to work for my needs. It's the basis of a solution, which would be different depending on every use case.

Good luck!

Dan Horton
  • 371
  • 3
  • 11