3

Here is my idea: After registing, an email will be sent to the user. After the user verifies the email, the new account with user's info will be added to Firebase. If not, the account won't be added. But i don't know how to do it.

Here is my code:

auth.createUserWithEmailAndPassword(email, password)
        .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    FirebaseUser user = auth.getCurrentUser();
                    FirebaseDatabase database = FirebaseDatabase.getInstance();
                    DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
                    DatabaseReference usersRef = ref.child("shop").child("Users");
                    String userId = usersRef.push().getKey();
                    final Map<String, Object> dataMap = new HashMap<String, Object>();
                    Users temp=new Users(email,user.getUid(),fullname);
                    usersRef.child(user.getUid()).setValue(temp);
                } else {
                    email_txt.setError(
                        "The email address is already in use by another account.");
                }
            }
        });
Jose Da Silva Gomes
  • 3,814
  • 3
  • 24
  • 34
Linklink
  • 31
  • 1
  • 2

1 Answers1

3

The simplest way to do this is to allow the user to "be created," but directly after login, check if the user's email is verified; if not, send them to a verification page in the app that warns them that they cannot access the app without a verified email address.

You can then delete accounts that are not verified with a firebase function that is regularly called with a cron job.

Here is the admin function I use that runs monthly (it uses typescript rather than javascript):

export const AutoDeleteUser = functions.https.onRequest((req, res) => {
    const currentTime = new Date().getTime();
    const month1 = currentTime - 2628000000;
    const month2 = currentTime - (2628000000 * 2);
    /* month1 and month2 are set so only users whose accounts are between one and two months old should be deleted
     * signupDate is how I find out how old the account is or in this case, how long its existed without verificaion
    */

    return userRef.orderByChild("signupDate").startAt(month2).endAt(month1).once("value")
    .then((snap) => {
        const uidList : string[] = [];
        snap.forEach(childSnap => {
            const uid = childSnap.key;
            uidList.push(uid);
            return admin.auth().getUser(uid).then((userRecord) => {
                if(userRecord.emailVerified) {
                    return false;
                } else {
                    return admin.auth().deleteUser(uid).then(() => {
                        return true;
                    },(reason) => {
                        console.error("Error deleting user " + uid + " : " + reason);
                        return false;
                    });
                }
            }, (reason) => {
                console.error("Error getting user " + uid + " : " + reason);
            }).then((wasDeleted) => {
                if(wasDeleted) {
                    console.log("User auto-deleted: " + uid);
                }
            });
        });
        return uidList
    }).then((uidList) => {
        res.send(uidList.join());
    });
});

To conserve some energy and track how long an account has existed, I have also added a signupDate node to index the users and prevent the function from including the users whose accounts have already been tested for email verification.

From testing this works without a hitch, but this is really just one solution to your problem that works while maintaining all of firebase's admin tools like email verification.

I also have a function that removes the user's account from the database when the account is deleted here for reference if it helps:

export const DeleteUser = functions.auth.user().onDelete((event) => {
    const uid = event.data.uid;
    return userRef.child(uid).remove((error) => {
        if (error !== null) {
            console.error("Error deleting user",error);
        }
    }).then(() => {
        console.log("User Data Deleted");
    });
});
Drei
  • 669
  • 1
  • 6
  • 22
  • Please let me know if you are unfamiliar with functions or if I skipped over something important. (I really have only included the code I could easily copy for you, I can also rewrite this in js if it would help) – Drei Apr 07 '18 at 17:53