0

I'm building an APP and using Firestore to create a collections of Users. Before adding the new user to the collection i need to check within the collection if the email is already in use and for this i've built two methods: one for reading the collection looking for an user with that email and the other one to adding the new user IF everything is ok. But no matter what I do, the add method always executes first leading to the validation being useless. I guess it's has something to do with the methods priority withing Firebase but i really couldn't pull out with a solution

Here's the two methods The first one it's validation and the second one it's the add

private boolean createFirestoreUser(final String identificador) {
    final boolean[] isValid = {true};
    FirebaseFirestore.getInstance().collection("Usuarios")
            .get()
            .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                @Override
                public void onComplete(@NonNull Task<QuerySnapshot> task) {
                    for (QueryDocumentSnapshot document : task.getResult()) {
                        if(identificador.equals(document.getString("identificador")))
                            isValid[0] = false;
                    }

                }
            });
    return isValid[0];
}

private void createUser(Usuario novoUsuario) {
    FirebaseFirestore.getInstance().collection("Usuarios")
        .add(novoUsuario)
        .addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
            @Override
            public void onSuccess(final DocumentReference documentReference) {
                documentReference
                        .update("id", documentReference.getId())
                        .addOnSuccessListener(new OnSuccessListener<Void>() {
                            @Override
                            public void onSuccess(Void aVoid) {
                                loginSessionManager.createLoginSession(documentReference.getId());
                                loginSessionManager.checkLogin(this.getClass());
                            }
                        })
                        .addOnFailureListener(new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                            }
                        });
            }
        })
        .addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                snackbar.showMensagemLonga(v,e.getMessage());
            }
        });
}

The second one is ALWAYS being called first no matter the order i use on the button listener. I've debbuged and it really enters in the isValid[0] = false after the user is added

  • There is no way you can return `isValid[0]` as a result of a method. Firebase API is asynchronous and you need to wait for the data. So please check the duplicate to see how can you solve this using a custom callback. – Alex Mamo Nov 19 '20 at 10:59

1 Answers1

0

Where are you calling the methods?

You could just call the createUser inside of the .addOnSuccessListener this way it will not be called until the valdiation is returned.

Something like:

    .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                @Override
                public void onComplete(@NonNull Task<QuerySnapshot> task) {
                    for (QueryDocumentSnapshot document : task.getResult()) {
                        if(identificador.equals(document.getString("identificador")))
                            isValid[0] = false;
                        else
                            createUser(novoUsuario)

                    }

                }

The reason why I'm asking where you are calling the methods is because your variable might be by default true which would trigger the second function before the async listener is returned therefore calling the second method before the validation is made.

So the alternative would be to call the register method inside the same mehrod where you are validating or if what I'm assuming that you have a boolean declared first to see if you call the create method, just have it false as default and make sure to be calling it after the async .OnCompleteLister is finished.

Louis C
  • 645
  • 5
  • 12