Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Waiting for document created in trigger in android app

I have an android app using firebase. When the user registers I have a trigger on firebase that creates a document in a collection with the default data for the user.

This is the code of the function used as a trigger on firebase:

    exports.sendWelcomeEmail = functions.auth.user().onCreate((user) => 
    {  
        var userCoinsCol = db.collection('user_data');
        userCoinsCol.doc(user.uid).set({
            coins : 100, // some another information for user you could save it here.
            active: true,
            completedRewards: 0
        })
        .then(() => {
            console.log("done");
            return;
        })
        .catch((err) =>
        {
            console.log("Error creating data for just created user. => "+err);
            return;
        });
    });

All this works perfectly. The problem is that after registering, I need the user data and it seems sometimes when the user registers it is not ready for the app to use in the next activity.

So, my question is, is there any way for the android app to wait for the trigger to create that document before moving to the next activity that will use that user data?

As you can guess this only happens firt time the user registers. Later if the user wants to use the app again everything works ok because the user data was created just after user registered.

Edit: After a bit of playing I have come with this solution, but it seems not too performant because it can receive a lot of documents. I just add it for reference:

public void CreateAccount()
{

    if(!TextUtils.isEmpty(emailreg.getText()) && !TextUtils.isEmpty(passreg.getText()))
    {
        mAuth.createUserWithEmailAndPassword(emailreg.getText().toString(), passreg.getText().toString())
        .addOnCompleteListener(this, new OnCompleteListener<AuthResult>()
        {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task)
            {

                progressBar.setVisibility(View.INVISIBLE);

                if (task.isSuccessful())
                {
                    // Sign in success, update UI with the signed-in user's information
                    final FirebaseUser user = mAuth.getCurrentUser();

                    // ----> Start waiting for the user_data document to be created and go to the next activity
                    FirebaseFirestore db = FirebaseFirestore.getInstance();
                    final EventListener<QuerySnapshot> listener = new EventListener<QuerySnapshot>() {
                        @Override
                        public void onEvent(@javax.annotation.Nullable QuerySnapshot queryDocumentSnapshots, @javax.annotation.Nullable FirebaseFirestoreException e) {
                            List<DocumentSnapshot> documents = queryDocumentSnapshots.getDocuments();

                            boolean found = false;
                            for(DocumentSnapshot ds : documents)
                            {
                                if(ds.getId().equals(user.getUid()))
                                {
                                    Intent intent = new Intent(LoginActivity.this, MainActivity.class); // Call the AppIntro java class
                                    startActivity(intent);
                                }

                            }
                        }
                    };

                    db.collection("user_data").addSnapshotListener(listener);

                } else
                {
                    // If sign in fails, display a message to the user.

                    Toast.makeText(LoginActivity.this, getString(R.string.tryagain), Toast.LENGTH_SHORT).show();

                }

                // ...
            }
        });

    }else
    {
        Toast.makeText(LoginActivity.this, getString(R.string.tryagain), Toast.LENGTH_SHORT).show();
        progressBar.setVisibility(View.INVISIBLE);

    }


}
like image 904
Notbad Avatar asked Mar 05 '26 17:03

Notbad


1 Answers

So, my question is, is there any way for the android app to wait for the trigger to create that document before going forward to the next activity that will create that user data?

Of course it is, by adding a complete listener. This means that you can go further only when the data is written successfully to the database. When you are using DocumentReference's set() method, the object that is returned is of type Task, so you can simply use addOnCompleteListener().

yourDocumentRef.set(yourObject).addOnCompleteListener(new OnCompleteListener<Void>() {
    @Override
    public void onComplete(@NonNull Task<Void> task) {
        if (task.isSuccessful()) {
            //Do what you need to do
        }
    }
});

Edit:

If the user document is added to the Cloud Firestore database via Coud Functions, you can either change the logic of your app and create the user document client side along with Security Rules which are mandatory so your users cannot play with the data. Or you attach a snapshot listener to verify the data in realtime. Once the document is created, go ahead with logic.

like image 173
Alex Mamo Avatar answered Mar 08 '26 06:03

Alex Mamo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!