0

I am trying to figure out a clean and simple way to obtain the uid resulting from a call to createUser() when working with the Java SDK. This is easy to do when working with the Javascript SDK (e.g., this question/answer). I've also seen the question raised on Stackoverflow in the context of the Firebase iOS API where it apparently isn't so easy. My problem is how to do it using the Firebase Java SDK. Specifically, my use case is the same as that in the iOS-related question, i.e. allow an Admin user to create user accounts (email/password authentication) and also store other info about the created user in Firebase with the uid as the key. Knowing and using the uid as a key is essential in that it is the basis for the security rules.

I've seen a couple of proposed solutions, both of which involved some procedure to be carried out after the new user account has been created. These are

Either way I have a convoluted solution with multiple async callbacks to deal with an issue that is trivial when using the Javascript API.

I therefore have three specific questions:

  1. Is there currently a better approach than the two I've listed above?
  2. If I use the 2nd approach and login as the newly created user, doesn't that over-ride the Admin token (i.e., log-out the admin who created the user) which in turn means new security rules apply?
  3. Is there any expectation that the Android & Java SDK's will be upgraded anytime soon so that the createUser() API is the same as the Javascript version?

UPDATE: Digging deeper and experimenting a bit I found the answers to my questions. It turns out that the API documentation provided by Firebase is out of date and/or inconsistent.

Re Q1: According to the Javadoc for createUser() the the only available callback handler is a Firebase.ResultHandler. However according to the Changelog, the API Reference document, and the documentation on Creating User Accounts, a Firebase.ValueResultHandler may be used as well. This provides direct access to the UID

Re Q2: The answer is yes. Authenticating the newly created user account results in the replacement of the auth token.

Re Q3: The real question should be "When are the Firebase folks going to update the Javadoc?" Or maybe a better question is "Why are new versions of the SDK being released without updated and accurate documentation?"

Community
  • 1
  • 1
LJ in NJ
  • 196
  • 1
  • 1
  • 12

2 Answers2

3

The following code is the correct way to deal with creating a new user

Firebase ref = new Firebase("https://<YOUR-FIREBASE>.firebaseio.com");
    ref.createUser("harry@foo.com", "badPassword", new Firebase.ValueResultHandler<Map<String, Object>>() {

    public void onSuccess(Map<String, Object> result) {
        System.out.println("New account with uid: " + result.get("uid"));
    }

    public void onError(FirebaseError firebaseError) {
        // there was an error
    }
});

I've updated the question to explain the reasons.

LJ in NJ
  • 196
  • 1
  • 1
  • 12
0

Try this. This is for the newer version of Firebase that came out in the most recent Google I/O. I am not promoting this new version or putting the older version down. I am just stating this as an alternative to the solution above:

mAuth = FirebaseAuth.getInstance();

//creates the user with email and password...make this another type of login if you want
mAuth.createUserWithEmailAndPassword(mEmail, mPassword).addOnCompleteListener(signup.this, new OnCompleteListener<AuthResult>() {
    @Override
    public void onComplete(@NonNull Task<AuthResult> task) {
        if (task.isSuccessful()) {
            //do something
        }
    }
});

Now you can add an AuthStateListener. You will have to put code in the onCreate, onStart, and onStop methods. Note that the above code can go in any reasonable method (e.g. onCreate, onStart, onResume, etc.). Here we go:

FirebaseAuth mAuth;
FirebaseAuth.AuthStateListener mAuthListener;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_something);

    mAuth = FirebaseAuth.getInstance();
    mAuthListener = new FirebaseAuth.AuthStateListener() {
        @Override
        public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
            FirebaseUser user = firebaseAuth.getCurrentUser();
            if(user != null){
                //check for null to prevent NullPointerException when dealing with user
                if(!user.getUid().matches("")){
                    //make this check just in case...I've experienced unexplainable glitches here
                    String uid = user.getUid();
                    //do more stuff with Uid
                }
            }
        }
    }
}

@Override
public void onStart(){
    super.onStart();
    mAuth.addAuthStateListener(mAuthListener);
}

@Override
public void onStop(){
    super.onStop();
    if(mListener != null){
        mAuth.removeAuthStateListener(mAuthListener);
    }
}

In the end, what happens is, once the user is created (and signed in at the same time), the mAuthListener makes a callback (it executes whatever is inside the mAuthListener, which, in this case, is getting the user's UID and doing other stuff with it). If you need help with this new Firebase in Android, here is a link to help you out: https://firebase.google.com/docs/android/setup

Anish Muthali
  • 782
  • 2
  • 7
  • 20