adriancarriger / angularfire2-offline

🔌 A simple wrapper for AngularFire2 to read and write to Firebase while offline, even after a complete refresh.
https://angularfire2-offline.firebaseapp.com/
MIT License
207 stars 48 forks source link

Unsubscribe doesn't prevent a call to firebase (=> permission denied) #50

Closed mparpaillon closed 7 years ago

mparpaillon commented 7 years ago

Hi, First of all, thanks for this great lib.

Here is my use case: I need the user uid to make a request to firebase so I have 2 nested Observables. One watching for user change (afAuth.authState.subscribe(user => ...)), another one watching for data change (this.db.list('flags/' + user.uid).subscribe(userFlags => ...)). When I sign out, even if I unsubscribe before the signout, the call is still made and I get a permission denied.

I'm pretty sure this is a "angularfire2-offline" issue since everything works fine if I replace my AngularFireOfflineDatabase import by the angularfire2 one AngularFireDatabase.

Thanks a lot

EDIT: Linked issue https://stackoverflow.com/questions/45276430/angularfire2-nested-observables-on-auth-change-and-permission-denied/45367331#45367331

adriancarriger commented 7 years ago

Hi @mparpaillon, there is an undocumented feature called reset that may help solve your issue.

Usage

You can call the method when a user signs out like this:

onUserSignout() {
  this.afoDatabase.reset()
}

Considerations

This will remove all offline data which means if you have writes made while offline they will not complete. This could potentially result in lost data.

Feedback

I would love to get feedback on this feature! I'm waiting to officially document it for the following reasons:

Please let me know what you experience. Thank you! 👍

mparpaillon commented 7 years ago

Thanks adriancarriger, but I don't want to remove all offline datas, only one specific subscribe to avoid a permission denied. I guess the lib should listen to "unsubscribe" calls to avoid an unwanted call like in this example below:

this.subFlags = this.db.list('user_flags/' + user.uid).subscribe(...);
this.subFlags.unsubscribe();

The ref includes the user.uid and a rule on firebase prevents any user to access other user datas like this one. I really want the unsubscribe to prevent from other calls once signed out.

adriancarriger commented 7 years ago

Hi @mparpaillon, you're in luck.. the reset method does accept a string argument that will allow reseting a specific reference like this:

onUserSignout() {
  this.afoDatabase.reset('my/firebase/ref')
}

The reason unsubscribe does not remove offline user data is to support the use case where a developer would like to free up application memory and still have that data available offline in the future.

Hope that solves your issue!

mparpaillon commented 7 years ago

@adriancarriger Works great ! Thanks a lot :)

mparpaillon commented 7 years ago

@adriancarriger Arf, I still have a problem. Do I need to call reset() on each call like object(ref).set(value) or object(ref).remove() ?

Let's say my user, during the time he's logged in, saves 14 values and removes 5 other values, when he signs out, to prevent from getting a "permission denied" do I need to reset 19 ref ??

Is there a way to avoid this ? Is there a way to add a condition to a call ?

If the user has signed out, I don't want the calls including the user.uid to be made, because that gives me a "permission denied" which crashed the app.

adriancarriger commented 7 years ago

With the way it currently works you could:

mparpaillon commented 7 years ago

Ok thank you :)

adriancarriger commented 7 years ago

No problem!