4

After registering with Firebase Authentication "Email / Password",saving e-mail without verification.I have application with Flutter firebase. When someone registers, I direct them to an email verification page and hold them there until they verify the email.The problem is that if someone uses my email and deletes app without verifying it, the mail still remains in the database.How do we delete unverified email addresses?

Raghim Najafov
  • 315
  • 3
  • 15
  • Hey Frank, Sorry for being late.There was a different urgent problem, so I cannot deal with this issue right now, but I will return to this issue as soon as possible.I thought Flutter firebase had a simple way to do this.I think it's easier and safer to sign in with "email link (passwordless sign-in)". I will return after trying it, considering your comments. @FrankvanPuffelen – Raghim Najafov Apr 25 '21 at 16:25

3 Answers3

5

You can run a scheduled cloud function every day that checks for unverified users and deletes them. That also means you would have to use Admin SDK and cannot be done in Flutter. You can create a NodeJS Cloud Function with the following code and run it.

exports.scheduledFunction = functions.pubsub.schedule('every 24 hours').onRun((context) => {
    console.log('This will be run every 24 hours!');
    const users = []
    const listAllUsers = (nextPageToken) => {
        // List batch of users, 1000 at a time.
        return admin.auth().listUsers(1000, nextPageToken).then((listUsersResult) => {
            listUsersResult.users.forEach((userRecord) => {
                users.push(userRecord)
            });
            if (listUsersResult.pageToken) {
                // List next batch of users.
                listAllUsers(listUsersResult.pageToken);
            }
        }).catch((error) => {
            console.log('Error listing users:', error);
        });
    };
    // Start listing users from the beginning, 1000 at a time.
    await listAllUsers();
    const unVerifiedUsers = users.filter((user) => !user.emailVerified).map((user) => user.uid)

    //DELETING USERS
    return admin.auth().deleteUsers(unVerifiedUsers).then((deleteUsersResult) => {
        console.log(`Successfully deleted ${deleteUsersResult.successCount} users`);
        console.log(`Failed to delete ${deleteUsersResult.failureCount} users`);
        deleteUsersResult.errors.forEach((err) => {
            console.log(err.error.toJSON());
        });
        return true
    }).catch((error) => {
        console.log('Error deleting users:', error);
        return false
    });
});
Dharmaraj
  • 47,845
  • 8
  • 52
  • 84
  • Is this the first time I've found a practical use case for recursion? I am blown away! Also, this looks like a great solution and will be using this a cron job. Additionally, you could check the user's creation date. If it's less than x days old, you could leave it; giving them some additional time to verify their account... just incase they created the account 2 minutes before the cron job executes – Cooper Scott May 27 '21 at 22:42
  • @SizzlingSquiggle thanks for the creation time verification tip! Yes, recursive functions are handy xD – Dharmaraj May 28 '21 at 12:12
4

This works just perfect:

const functions = require("firebase-functions");
const admin = require("firebase-admin");

admin.initializeApp();
exports.scheduledFunction = functions.pubsub
  .schedule("every 24 hours")
  .onRun((context) => {
    console.log("This will be run every 24 hours!");
    var users = [];
    var unVerifiedUsers = [];
    const listAllUsers = async (nextPageToken) => {
      // List batch of users, 1000 at a time.
      return admin
        .auth()
        .listUsers(1000, nextPageToken)
        .then((listUsersResult) => {
          listUsersResult.users.forEach((userRecord) => {
            users.push(userRecord);
          });
          if (listUsersResult.pageToken) {
            // List next batch of users.
            listAllUsers(listUsersResult.pageToken);
          }
        })
        .catch((error) => {
          console.log("Error listing users:", error);
        });
    };
    // Start listing users from the beginning, 1000 at a time.
    listAllUsers().then(() => {
      unVerifiedUsers = users
        .filter((user) => !user.emailVerified)
        .map((user) => user.uid);
      admin
        .auth()
        .deleteUsers(unVerifiedUsers)
        .then((deleteUsersResult) => {
          console.log(
            `Successfully deleted ${deleteUsersResult.successCount} users`
          );
          console.log(
            `Failed to delete ${deleteUsersResult.failureCount} users`
          );
          deleteUsersResult.errors.forEach((err) => {
            console.log(err.error.toJSON());
          });
          return true;
        })
        .catch((error) => {
          console.log("Error deleting users:", error);
          return false;
        });
    });
  });



Olu Teax
  • 149
  • 1
  • 5
2

You can delete users through the Firebase Admin SDK.

You'll need a list of unverified users, either by listing all users and filtering it down, or from somewhere you store this yourself, and then you can delete the unverified users.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807