0

I use the Firebase realtime database in my Android app where disk persistence is enabled.

When the user opens the app for the first time I read auth status, if that is null I show the login screen and after the login, I will get the username stored against this user id in the realtime database.

If the username is null then I will show username setup screen where he will choose the unique username for him. The problem arises when the connection goes off during the username setup phase. username is not yet written to the database but when he opens the app next time username will not be null as Real-time database gives me value stored in the cache. So I proceed to the home screen but what if someone else chooses the same username during this phase?

I maintain two-way mapping between uid and username as suggested in this answer

I can't use transaction because at a time transcation can be run only on one path but in my case, I have to automatically update two paths.

I also have security rules setup up for maintaining unique username but what to do with the users who are already crossed the username setup screen.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
Praveena
  • 6,340
  • 2
  • 40
  • 53
  • You can use shared preferences like i did.Add oncomplete listener for set value method.and when its complete write data to phone.So this way if username is not written to firebase phone will also return null username. – uzaysan Jan 06 '19 at 08:20
  • But if there is connection drop between setValue and on completion callback? – Praveena Jan 06 '19 at 08:22
  • Ask user to choose username one more time.Choosing another username is better than using a usename that doesnt exist. – uzaysan Jan 06 '19 at 08:25
  • Also firebase can wait until user connect. – uzaysan Jan 06 '19 at 08:26

1 Answers1

0

What if someone else chooses the same username during this phase?

Everytime you want to perform a write operation for a user name, you need to make sure it's unique. To check if a user name exists in a Firebase realtime database, a query like this is required:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Query query = rootRef.child("users").orderByChild("userName").equalTo(userName);
query.addValueEventListener(/* ... */);

So if the user tries to set/change the user name while offline, the above query is added to a queue. Once the user regains the connection, every change that is made while offline, will be updated on Firebase servers. With other words, the above query will be commited on the server. So if a user chooses a user name that already exists in the database while offline, when is back online, he'll receive a message that user name already exists.

I can't use transaction because at a time transcation can be run only on one path but in my case, I have to automatically update two paths.

I cannot use transaction because it can be run only on one path, you cannot use transactions at all. Transactions are not supported for offline use. This is because a transaction absolutely requires round trip communications with server in order to ensure that the code inside the transaction completes successfully. So, transactions can only execute when you are online.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • in your username checking query, event will fire immediately with value being null even if value exist in the DB and there is a connection and I have to show username doesn't exist in the DB and user can take it – Praveena Jan 06 '19 at 18:09
  • If the user name is not set and you have no internet connection, yes, the value returned it will be `null` even if the value exist in the database. But this is the normal behaviour since you are offline and you cannot check what's online. To be able to display this message `username doesn't exist in the DB`, you definitely should be online so you can use that query and return the correct data, right? – Alex Mamo Jan 07 '19 at 08:30