'Flutter Firebase - How to open the app when tapping on email verification link send by Firebase?

I am able to send an email verification link through Firebase on my flutter app. But I want to modify the link so that when the user taps on it, it will take them to an app screen defined by me. So basically deep linking. I looked around and found resources for deep linking but they all dealt with custom urls with things like newsletters in mind.

But I am looking to modify the verification email that Firebase sends in a deep link that opens a particular screen in the app.



Solution 1:[1]

After User register account you need to route to a new class where in the init function you will send a sendEmailVerification();

See the below code

user = auth.currentUser!; 
user.sendEmailVerification();

In the initState() make a timer also which will check is the email is verified periodiclly.

so, say after every five seconds call this function so, it will be checking the email is verified or not.

Refer the below function

Future<void> checkEmailVerified() async {
    user = auth.currentUser!;
    await user.reload();
    if (user.emailVerified) {
      timer.cancel();
      Navigator.of(context).pushNamed('/home');
    }
  }

If the user email gets verified pass the user to the Home screen

and also dispose the timer

Refer the full code given below

import 'dart:async';

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:service_provider/constant/constant.dart';
import 'package:sizer/sizer.dart';

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

class _VerifyScreenState extends State<VerifyScreen> {
  final auth = FirebaseAuth.instance;
  late User user;
  late 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(
      backgroundColor: Colors.white,
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Padding(
              padding: const EdgeInsets.all(0.0),
              child: Image.asset('assets/images/gif.gif',
                  fit: BoxFit.contain, height: 18.h),
            ),
            Padding(
              padding: const EdgeInsets.all(25.0),
              child: RichText(
                text: TextSpan(
                  text: 'An email has been sent to ',
                  style: GoogleFonts.spartan(
                    color: Colors.black,
                    // textStyle: Theme.of(context).textTheme.headline4,
                    fontSize: 14,
                    fontWeight: FontWeight.w400,
                  ),
                  children: <TextSpan>[
                    TextSpan(
                      text: '"${user.email}"',
                      style: GoogleFonts.spartan(
                        color: Color(Const.primary),
                        // textStyle: Theme.of(context).textTheme.headline4,
                        fontSize: 14,
                        fontWeight: FontWeight.w500,
                      ),
                    ),
                    const TextSpan(text: ' please verify'),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Future<void> checkEmailVerified() async {
    user = auth.currentUser!;
    await user.reload();
    if (user.emailVerified) {
      timer.cancel();
      Navigator.of(context).pushNamed('/home');
    }
  }
}

Note

Some user can skip this process by just closing the app from here. so, what you can do is when the user again loginin check if the user is verifed if the user's email is not verified again come to the verification page

Thank you

Solution 2:[2]

After sending verification link you have to use Firebase deep linking plugin and in Firebase console you create your own dynamic links and you should change your verification mail domain as dynamic links domain. You can this from authentication section template in Firebase console.

In first screen of your flutter screen make stateful and in initstate call function initDynamicLinks().

Dynamic link in firebase: https://customlink.page.link/auth

Future<void> initDynamicLinks() async {
    dynamicLinks.onLink.listen((dynamicLinkData) async {
      final Uri deepLink = dynamicLinkData?.link;
      print("deepLink $deepLink");
      if (deepLink.path == "/auth") {
        print(deepLink);
        Get.toNamed(Routes.LOGIN_EMAIL_SCREEN);
      }
    }).onError((error) {
      print('onLink error');
      print(error.message);
    });
  }

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 Alan Bosco
Solution 2 Dharman