Sign In widget is rebuilt everytime sign in button is clicked

Viewed 26

AuthProvide Class*

class AuthProvider extends ChangeNotifier {

  final FirebaseAuth _auth = FirebaseAuth.instance;

  bool get isSignedIn => _auth.currentUser != null;

  User get currentUser => _auth.currentUser!;

  String message = '';

  Future<String> signIn(
      {required String email, required String password}) async {
    try {
      await _auth.signInWithEmailAndPassword(email: email, password: password);
      notifyListeners();
      message = 'Successfully signed in';
      return message;
    } on FirebaseAuthException catch (e) {
      message = getMessageFromErrorCode(e.code);
      return message;
    }
  }
}

I call the isSignedIn getter in main using a consumer and return login screen or home screen based on the bool value.

SignIn Widget

                  SignInBar(
                    label: 'Sign in',
                    color: const Color(0xff092E34),
                    onPressed: () async {
                      FocusScope.of(context).unfocus();
                      if (_formKey.currentState!.validate()) {
                        _formKey.currentState!.save();
                        String message = await context
                            .read<AuthProvider>()
                            .signIn(email: _email, password: _password);
                        SnackBar snackBar = SnackBar(content: Text(message));
                        ScaffoldMessenger.of(context).showSnackBar(snackBar);
                      }
                    },
                  ),

When SignIn onPressed is called my widget gets rebuilt and the form is cleared. how to stop it from rebuilding?

1 Answers

Ok so I don't know the specific reason for the above question but I tried with a different approach for auth provider and truly it has solved my problem. I am posting this in the answer because I want to share this auth provider template with everyone since I faced lot problem finding one with null safety.

Auth Provider

class AuthProvider with ChangeNotifier {
  bool _isLoading = false;
  bool get isLoading => _isLoading;

  FirebaseAuth firebaseAuth = FirebaseAuth.instance;

  Future<String?> register(String email, String password) async {
    setLoading(true);
    try {
      UserCredential authResult = await firebaseAuth
          .createUserWithEmailAndPassword(email: email, password: password);
      User? user = authResult.user;
      setLoading(false);
      notifyListeners();
      return user != null ? null : 'An error Occurred';
    } on SocketException {
      setLoading(false);
      notifyListeners();
      return "No internet, please connect to internet";
    } on FirebaseAuthException catch (e) {
      setLoading(false);
      notifyListeners();
      return e.message;
    }
  }

  Future<String?> login(String email, String password) async {
    setLoading(true);
    try {
      UserCredential authResult = await firebaseAuth.signInWithEmailAndPassword(
          email: email, password: password);
      User? user = authResult.user;
      setLoading(false);
      notifyListeners();
      return user != null ? null : 'An error Occurred';
    } on SocketException {
      setLoading(false);
      notifyListeners();
      return "No internet, please connect to internet";
    } on FirebaseAuthException catch (e) {
      setLoading(false);
      notifyListeners();
      return e.message;
    }
  }

  Future logout() async {
    await firebaseAuth.signOut();
  }

  void setLoading(val) {
    _isLoading = val;
    notifyListeners();
  }

  Stream<User?> get user =>
      firebaseAuth.authStateChanges().map((event) => event);
}

Main.dart

MultiProvider(
            providers: [
              ChangeNotifierProvider<AuthProvider>.value(value: AuthProvider()),
              StreamProvider<User?>.value(
                value: AuthProvider().user,
                initialData: null,
              )
            ],
            child: MaterialApp(
              title: 'Revora',
              debugShowCheckedModeBanner: false,
              theme: ThemeData(
                visualDensity: VisualDensity.adaptivePlatformDensity,
                primarySwatch: Colors.teal,
                accentColor: Colors.amber,
                textTheme: AppTheme.textTheme,
                appBarTheme: AppBarTheme(
                  backgroundColor: Colors.white,
                  elevation: 0.0,
                ),
                platform: TargetPlatform.android,
              ),
              home: Wrapper(),
            ),
          );

If this is helpful pls upvote the answer so that everyone can gain from it.

Related