skip to Main Content

I’m trying to sign in the user in anonymous mode automatically using firebase anonymous authentication, only if the user is not already registered and signed. Using shared preferences, I check during the appearing of the splash screen if the user is already signed in as follows:

getValidationData().whenComplete(() async {
  await Future.delayed(Duration(milliseconds: 4000));
  // ignore: use_build_context_synchronously
  Navigator.pushReplacement(
      context,
      MaterialPageRoute(
        builder: (context) =>
            finalEmail == null ? LoginScreen() : HomeScreen(),
      ));
});

in the getValidationData() function, this is the code:

  Future getValidationData() async {
    final SharedPreferences sharedPreferences =
        await SharedPreferences.getInstance();
    var obtainedEmail = sharedPreferences.getString('email');
    setState(() {
      finalEmail = obtainedEmail;
    });
  }

As you may have noticed if no email found in shared preferences the user will be redirected to the login screen. What I want is to redirect the user to the home page as a guest (Anonymous) using the firebase service which is implemented in my code as follows:

class authService {
  final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;

  User? get currentUser => _firebaseAuth.currentUser;

  Future<User> getOrCreateUser() async {
    if (currentUser == null) {
      await _firebaseAuth.signInAnonymously();
    }
    return currentUser!;
  }
}

My problem is that I am not sure where to create the anonymous authentication if no shared preferences found, I’ll appreciate any help.

2

Answers


  1. Chosen as BEST ANSWER

    I have solved my problem by doing a little tweak in the code, so instead of checking if the user already logged in like this:

    getValidationData().whenComplete(() async {
      await Future.delayed(Duration(milliseconds: 4000));
      // ignore: use_build_context_synchronously
      Navigator.pushReplacement(
          context,
          MaterialPageRoute(
            builder: (context) =>
                finalEmail == null ? LoginScreen() : HomeScreen(),
          ));
    });
    

    we can log the user anonymously if no shared preferences information found like this:

     getValidationData().whenComplete(() async {
                  await Future.delayed(Duration(milliseconds: 4000));
                  // ignore: use_build_context_synchronously
                  if (finalEmail == null) {
                    // ignore: use_build_context_synchronously
                    await authService().getOrCreateUser();
                    Navigator.pop(context);
                    Navigator.push(
                        context,
                        MaterialPageRoute(
                            builder: (context) => const HomeScreen()));
                  } else {
                    Navigator.push(
                        context,
                        MaterialPageRoute(
                            builder: (context) => const HomeScreen()));
                  }
                });
    

    Hopefully it will help anyone trying to achieve the same approach.


  2. Assumptions

    • There are 3 types of use cases:

      1. User is already signed in and registered
      2. User is signed out but registered
      3. User is signed out and not registered
    • Using shared_preferences or any kind of local storage solution to differentiate between 2 and 3 is a bad idea. Local storage can be wiped out. Hence I am assuming we cannot differentiate between 2 and 3.

    • In case of 1, user is redirected to homepage

    • In case of 2 and 3, you can redirect the user to login screen and give them an option to enter without signing in.


    What to do:

    1. If the user is signed in, you’ll get a User result from _firebaseAuth.currentUser

    2. If you get null from _firebaseAuth.currentUser then, signIn user anonymously, you don’t need sharedPreferences.


    Where to do it:

    Please call these functions in splashscreen:

    Future<bool> isUserLoggedIn() async{
      return FirebaseAuth.instance.currentUser != null;
    }
    
    Future<void> handleUserRedirection() async {
      final bool userLogin = await isUserLoggedIn();
      Navigator.pushReplacement(
          context,
          MaterialPageRoute(
            builder: (context) =>
                !userLogin? LoginScreen() : HomeScreen(),
          ));
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search