I'm relatively new with Android/programming... I'm trying to design an app that uses Firebase as the backend (although the problems I am having would exist for any app that tries to make immediate decisions based on remote data).
I feel like there is a smarter way to do what I'm trying to do.
The requirements are (the way I'm thinking about problem):
- Design an app where new users sign in and register (two separate things), but the app will not allow them to use the app properly unless they have been expicitly (manually) authorized by a human via the Firebase database console. Existing/approved users will bypass these stages.
So... to solve this, I have thought:
When they first open the app, if they are not signed in, present them with a SignIn Activity.
If, upon successful sign-in, it is found they have not yet registered, then present a registration Activity.
If upon successful registration, it is found that they are not yet admin-approved, then exit the app with an alert dialog explaining they must wait longer for approval.
Sounds simple... so we could just have a MainActivity onResume() method like this:
@Override
protected void onResume(){
super.onResume();
// if not signed in, go to signIn/Create account activity
// (either we are signed in or we return from signin.java)
// if not signedUP/registered, then we go to signUP/register activity
// (either we are signed up or we return from register.java)
// is user admin-approved? if not, then we exit.
}
But the problems arise when we try to implement these "checks."
How do you check whether a user has already registered? I thought, well, we can just query the Firebase database... for example:
To find out if a user has already registered, we check for a branch (key) in the JSON tree of the Firebase DB that matches the signed in userID, then we know they have registered (because the registration activity would have created this record already)
To check whether they are admin-approved, we would check for a field such as:
'\firebase\user_id\isAllowed' = true.
This field would be set to false by default and set to true only if an admin manually sets the value in the database.
But these sort of remote checks will take time to execute... and the results are delivered via callback methods... so how can we "pause" the onresume method so that it waits for the result before continuing?? (we could 'nest' callbacks within callbacks: Firstcheck.onsuccess() { [Secondcheck.onsuccess() { [Thirdcheck.onsuccess() { // SUCCESS! }] } ] }
... but this seems like a bad idea.
Alright... so why not use shared preferences instead, and have the registration activity save a "user_progress" variable such as 1, meaning that they have completed the registration? This way the user's progress would be stored locally and could be immediately checked in the onresume()
logic.
But then this creates a new problem... that is what if the user re-installs the app? then the shared preferences are wiped and it would now believe that they are not registered... and mistakenly present them with the registration activity again.
I have individual solutions for these individual problems, but what results is a rat's nest of hard to follow code...
Has anyone else been stuck with this kind of problem? Where am I going wrong in my thinking? I feel like there is a fundamentally incorrect way that I'm approaching it... like procedural vs object oriented... and I'm wondering if anyone can address that.