flutterfirebasedartfirebase-authentication

Flutter Web/Firebase - Pressing back in browser bypasses verification process


When my user signs up I direct them to a page to inform them that they need to verify their email before continuing:

enter image description here

Here is my verification screen code:

  class VerifyScreen extends StatefulWidget {
  @override
  _VerifyScreenState createState() => _VerifyScreenState();
}

class _VerifyScreenState extends State<VerifyScreen> {
  final auth = FirebaseAuth.instance;
  User user;

  Timer timer;

  @override
  void initState() {
    user = auth.currentUser;
    user.sendEmailVerification();

    timer = Timer.periodic(
      Duration(seconds: 5),
      (timer) {
        checkEmailVerified();
      },
    );
    super.initState();
  }

  @override
  void dispose() {
    timer.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          height: MediaQuery.of(context).size.height * 0.8,
          width: MediaQuery.of(context).size.width * 0.8,
          child: Text(
              "An email has been sent to ${user.email} please verify before proceeding"),
        ),
      ),
    );
  }

  Future<void> checkEmailVerified() async {
    user = auth.currentUser;
    await user.reload();

    if (user.emailVerified) {
      Navigator.of(context).pushReplacement(
        MaterialPageRoute(
          builder: (context) => OurHomePage(),
        ),
      );
      timer.cancel();
    }
  }
}

Problem Statement: When I press the back arrow on my chrome browser:

enter image description here

I get returned to my homepage with the user signed in which I don't want. I would like my user to verify their email before being able to continue. Here's the drawer on my homepage after I press the back button without verifying the email:

enter image description here

I use provider to pass my user object around my app. Here is my main.dart:

  void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(
    MultiProvider(
      providers: [
        Provider(
          create: (_) => FirebaseAuthService(),
        ),
        StreamProvider<OurUser>(
            create: (context) =>
                context.read<FirebaseAuthService>().onAuthStateChanged),
      ],
      child: MaterialApp(theme: OurTheme().buildTheme(), home: OurHomePage()),
    ),
  );
}

I then user Consumer to consume that provider on my Homepage:

class OurHomePage extends StatefulWidget {
  @override
  _OurHomePageState createState() => _OurHomePageState();
}

class _OurHomePageState extends State<OurHomePage> {
  @override
  Widget build(BuildContext context) {
    return Consumer<OurUser>(
      builder: (_, user, __) {
        return ChangeNotifierProvider<SignInViewModel>(
          create: (_) => SignInViewModel(context.read),
          builder: (_, child) {
            return Scaffold(appBar: AppBar(title: Text("My Homepage")));
          },
        );
      },
    );
  }
}

Can anyone help me resolve the issue I'm facing? Thanks in advance.


Solution

  • On homepage check if user is logged in and when is, check if he has verified email. If he has, let him in, otherwise show him some message.