-1

I am making a flutter application where i need to register into firebase. First I have SignInPage() which uses Navigator to redirect to ResidentRegister().Here is the form for registering into the application. The problem is the ResidentRegister() page is not getting redirected to HomeScreen() upon successful Authentication of the user. The user is properly registered into the firebase and HomeScreen() appears after hotrestart of the application. I have used StreamProvider for the purpose which should listen to a stream of type 'Resident' which is my User data model based on whether it is null or not in the Wrapper() class. In the 'Wrapper' class, the stream is getting 'instance of resident'(when I print the value of resident variable), but the else block is not getting executed. This is probably happening due to usage of Navigator as when I remove the first screen that is SignInPage(), the ResidentRegister() screen is successfully getting redirected to HomeScreen(). I don't know why this happens as I have wrapped the MaterialApp to StreamProvider widget. Any help would be appreciated Thanks!

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamProvider<Resident>(
      create: (_)=> AuthService().resident,
      child: Consumer<Resident>(
        builder: (context, resident, _)
        {
          return MaterialApp(
              home: (user != null) ? HomeScreen() : SignInPage(),
          );
        },

      ),
    );
  }
}



class SignInPage extends StatelessWidget {
  SignInPage({this.title});
  final String title;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('JNMCH eLogBook'),
        centerTitle: true,
      ),
      body: SizedBox.expand(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Text('Sign In',
              style: TextStyle(
                color: Colors.teal,
                fontWeight: FontWeight.w300,
                fontSize: 65,
              ),),
            SizedBox(height: 35,),
            
            CustomButton(text: 'Sign In as a Resident', onPressed: ()=> Navigator.pushNamed(context, '/residentRegister')),
            SizedBox(height:8.0),
            CustomButton(text: 'Sign In as a Mentor', onPressed: () => Navigator.pushNamed(context,'/mentorSignIn')),
          ],
        ),
      ),
    );
  }
}
class ResidentRegister extends StatefulWidget {
  @override
  _ResidentRegisterState createState() => _ResidentRegisterState();
}

class _ResidentRegisterState extends State<ResidentRegister> {
  final AuthService _auth = AuthService();
  final _formKey = GlobalKey<FormState>();
  String _email;
  String _password;
  String _confirmPassword;
  String _error = '';
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: true,
      appBar: AppBar(
        title: Text('Register as a Resident'),
      ),
      body: SingleChildScrollView(
        child: Stack(
          children: <Widget>[
            Center(
              child: Padding(
                padding: const EdgeInsets.symmetric(vertical: 80.0, horizontal: 40.0),
                child: Card(
                  color: Colors.white,
                  elevation: 8.0,
                  child: Form(
                    key: _formKey,
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.end,
                      children: <Widget>[
                        SizedBox(height: 20,),
                        Text('Register',
                          style: TextStyle(
                            color: Colors.teal,
                            fontWeight: FontWeight.w300,
                            fontSize: 65,
                          ),
                        ),
                        SizedBox(height: 35,),
                        TextFormField(
                          validator: (val) => val.isEmpty ? 'Enter an email' : null,
                          decoration: InputDecoration(
                              hintText: 'Email'
                          ),
                          onChanged: (value) {
                            setState(() {
                              _email = value;
                            });
                          },
                        ),
                        SizedBox(height: 20,),
                        TextFormField(
                          validator: (val) => val.length < 6 ? 'Enter a password 6+ char long' : null,
                          decoration: InputDecoration(
                              hintText: 'Password'
                          ),
                          obscureText: true,
                          onChanged: (value) {
                            setState(() {
                              _password = value;
                            });
                          },
                        ),
                        SizedBox(height: 20,),
                        TextFormField(
                          validator: (val) => val!=_password ? 'Confirm Password must be same as password' : null,
                          decoration: InputDecoration(
                              hintText: 'Confirm Password'
                          ),
                          obscureText: true,
                          onChanged: (value) {
                            setState(() {
                              _confirmPassword = value;
                            });

                          },
                         ),
                        SizedBox(height: 20,),
                        Padding(
                          padding: const EdgeInsets.all(0),
                          child: ButtonTheme(
                            minWidth: 150,
                            height: 50,
                            child: RaisedButton(onPressed: () async {
                              if(_formKey.currentState.validate()){
                                dynamic result = await _auth.register( _email,_password);
                                if(result == null){
                                  setState(() {
                                    _error = 'Please supply a valid email';
                                  });
                                }
                              

                              }
                            },
                              color: Colors.teal,
                              child:
                              Text(
                                'Submit',
                                style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 20,),
                              ),
                              shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(28.0),
                                side: BorderSide(color: Colors.teal[100]),
                              ),
                            ),
                          ),
                        ),
                        SizedBox(height: 20,),
                        Text(_error, style: TextStyle(
                          fontSize: 14.0,
                          color: Colors.red,
                        ),),
                        SizedBox(height: 20,),
                        FlatButton(
                          color: Colors.white,
                          textColor: Colors.grey[600],
                          disabledColor: Colors.black,
                          disabledTextColor: Colors.black,
                          padding: EdgeInsets.all(8.0),
                          splashColor: Colors.teal,
                          onPressed: () {
                            Navigator.pop(context);
                          },
                          child: Text(
                            "Already have an account? Sign In!",
                            style: TextStyle(fontSize: 16.0),
                          ),
                        )
                      ],
                    ),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final AuthService _auth = AuthService();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Page'),
        actions: <Widget> [
          FlatButton.icon(

              onPressed: ()async {
                await _auth.signOut();
              },
              icon: Icon(Icons.person,color: Colors.white,),
              label: Text('Sign Out', style: TextStyle(color: Colors.white),)),
        ],
      ),
    );
  }
}
class AuthService{
  final FirebaseAuth _auth = FirebaseAuth.instance;

  // create resident user object based on Firebase User
  Resident _residentFromFirebaseUser(FirebaseUser user){
      return user!=null ? Resident(uid: user.uid) : null;
  }

  //auth change user stream
   Stream<Resident> get resident {
    return _auth.onAuthStateChanged
        .map(_residentFromFirebaseUser);

   }

   //register with email and password
   Future register(String email, String password) async{
    try{
      AuthResult result = await _auth.createUserWithEmailAndPassword(email: email, password: password);
      FirebaseUser user = result.user;
      print(user);
      return _residentFromFirebaseUser(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;
    }
}

}

class Resident{
  final String uid;
  Resident({ this.uid });

}
Falak Naz
  • 1
  • 2

1 Answers1

0

I believe you're using StreamProvider incorrectly. It shouldn't be:

StreamProvider<Resident>.value(value: ...)

Instead, try using:

StreamProvider<Resident>(
  create: (_) => AuthService().resident,
  child: Consumer<Resident>(
    builder: (context, resident, _) {
      // TODO: return home page or sign in page based on data
    },
  ),
);

That should subscribe to the stream and rebuild on new events.

bizz84
  • 1,964
  • 21
  • 34
  • I changed the code to: StreamProvider( create: (context)=> AuthService().resident, still not working – Falak Naz Jan 17 '21 at 10:15
  • Are you definitely using this correctly with the builder argument? return StreamProvider( create: (_) => AuthService().resident, builder: (context, snapshot) { // return home page or sign in page based on snapshot }, ); – bizz84 Jan 17 '21 at 20:46
  • I tried to use the builder parameter but compiler says it is deprecated with a strikethrough on the word 'builder' like this https://stackoverflow.com/questions/59100723/flutter-changenotifierprovider-builder-is-deprecated – Falak Naz Jan 18 '21 at 06:52
  • Still not working :( Edited the code above which I tried – Falak Naz Jan 19 '21 at 13:41