'Firebase auth email verification is useless because the user can access the app even if he doesn't click the confirmation link

I am struggling with the email verification on my flutter app. When i tried to implement the functionality, even if the user didn't validate his account, he was able to use his account with no problems. How can I do it so that the user can't access the app while the confirmation link isn't clicked so that people couldn't use emails they don't have access to? Here is the code

//On this file, I store all the login and sign in functionalities:
class AuthService {
  final FirebaseAuth _auth = FirebaseAuth.instance;
  final googleSignIn = GoogleSignIn();

  GoogleSignInAccount? _user;

  // create user object based on firebase user

  Users? _userFromFirebaseUser(User? user) {
    return user != null ? Users(uid: user.uid) : null;
  }

  // auth change user stream
  Stream<Users?> get user {
    return _auth.authStateChanges().map(_userFromFirebaseUser);
  }
  //register with email & psswrd
  Future registerWithEmailAndPassword(String email, String password) async {
    try {
      UserCredential result = await _auth.createUserWithEmailAndPassword(
          email: email, password: password);

      User? user = result.user;

      return _userFromFirebaseUser(user);
    } catch (e) {
      print(e.toString());
      return null;
    }
  }

  //sign out
  Future signOut() async {
    try {
      return await _auth.signOut();
    } catch (e) {
      print(e.toString());
      return null;
    }
  }
}

This is the main.dart file:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await Firebase.initializeApp();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return StreamProvider<Users?>.value(
      initialData: null,
      value: AuthService().user,
      child: MaterialApp(
        home: Wrapper(),
      ),
    );
  }
}

The wrapper file leads either to the authentication page or to the homepage:

class Wrapper extends StatelessWidget {
  const Wrapper({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final user = Provider.of<Users?>(context);

    //return either home or authenticate
    if (user == null) {
      return Authenticate();
    } else {
      return Home();
    }
  }
}


Solution 1:[1]

The email verification has nothing to do with the account creation itself, rather than verifying that the user is not a spam user. You can check if the user has his email verified like so FirebaseAuth.instance.currentUser.emailVerified this returns a bool and then you can accordingly plan your app flow.

Solution 2:[2]

You're right that there is a user created. You'll want to require emailVerified on your security rules and ui.

Then the issue of the user created, using that email: create a cloud function that evaluates your users at a time interval to check for emailVerified. At whatever age you decide, delete the user.

There's not much you can do here. Email verification is so spotty with spam filters, and phone numbers are transient enough to be problematic. I'm trying to get away from email, email/password entirely and require google and apple login only, which provides a verified email.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 esentis
Solution 2 jbryanh