DEV Community

Abdelouahedd
Abdelouahedd

Posted on

Login using firebase and flutter

Alt Text
In this article, I will show you how to create a login and register in firebase using Flutter.
First , create your project in firebase a,d activate a mode of authentification in firebase auth after configurate your project and put your file google-service.json in the folder app in project.

First we create a model of our user :


class User {
  String _id;
  String username;
  String email;
  String city;
  DateTime birthDay;
  String profileImg;
  String _password;
  double rank;

  User({
    String id,
    this.username,
    this.email,
    String password,
    this.city,
    this.birthDay,
    this.profileImg,
    this.rank = 0,
  })  : _id = id,
        _password = password;

  String get id => _id;

  void setId(String uuid) => _id = uuid;

  String get password => _password;

  factory User.fromRawJson(String str) => User.fromJson(json.decode(str));

  String toRawJson() => json.encode(toJson());

  factory User.fromJson(Map<String, dynamic> json) => User(
        id: json["id"],
        username: json["username"],
        email: json["email"],
        password: json["password"],
        city: json["city"],
        birthDay: (json["birthDay"] as Timestamp).toDate(),
        profileImg: json["profileImg"] == null ? null : json["profileImg"],
        rank: json["rank"],
      );
  Map<String, dynamic> toJson() => {
        "id": id == null ? null : id,
        "username": username,
        "email": email,
        "password": password,
        "city": city,
        "birthDay": birthDay,
        "profileImg": profileImg == null ? null : profileImg,
        "rank": rank,
      };

  @override
  String toString() {
    return """
    User : { \n
      username :  $username - \n
      email : $email - \n
      password : $password  -\n 
      city : $city -\n
      profileImg : $profileImg -\n
      rank : $rank\n
      }\n""";
  }
}
Enter fullscreen mode Exit fullscreen mode

After that we cant create a class that contient our methodes of sign in and sign ou :

class UserController {
  final FirebaseAuth _auth = FirebaseAuth.instance;
  User _user;
  UserController({User user}) : _user = user;

  Future signIn(String email, String password) async {
    try {
      await _auth
          .signInWithEmailAndPassword(email: email, password: password)
          .then((value) => this.getUser(value.user.uid))
          .timeout(new Duration(seconds: 60))
          .catchError(
            (onError) =>
                print("Error while sign in to app :${onError.message}"),
          );
      return _user;
    } catch (e) {
      print("Error while sign in to app :${e.message}");
      return null;
    }
  }

  Future<bool> signOut() async {
    try {
      await _auth.signOut();
      print("Success log out");
      return true;
    } catch (err) {
      print("Error while user sign out  : ${err.message}");
      return false;
    }
  }

  Future getUser(String uid) async {
    await Firestore.instance
        .collection("users")
        .document(uid)
        .get()
        .then((value) => {
              _user = User.fromJson(value.data),
              print("Returned user from getUser ${_user.toString()}")
            })
        .catchError((onError) =>
            print("Error while getting information of user  : $onError"));
  }

}
Enter fullscreen mode Exit fullscreen mode

after creating our logic of controlling data we move to create the UI of login and register:
firstly we create a class of Textfield :

class CustomTextField extends StatelessWidget {
  CustomTextField({
    this.icon,
    this.hint,
    this.obsecure = false,
    this.read = false,
    this.validator,
    this.onSaved,
    this.tap,
    this.textEditingController,
  });
  final FormFieldSetter<String> onSaved;
  final Function tap;
  final Icon icon;
  final String hint;
  final bool obsecure;
  final FormFieldValidator<String> validator;
  final TextEditingController textEditingController;
  final bool read;
  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.only(left: 20, right: 20, top: 5),
      child: TextFormField(
        readOnly: read,
        controller: this.textEditingController,
        onSaved: onSaved,
        validator: validator,
        autofocus: true,
        obscureText: obsecure,
        onTap: tap,
        style: TextStyle(
          fontSize: 15,
          color: Theme.of(context).primaryColor,
        ),
        decoration: InputDecoration(
            hintStyle: TextStyle(fontSize: 15, color: Colors.blue),
            hintText: hint,
            enabledBorder: OutlineInputBorder(
              borderRadius: BorderRadius.circular(30),
              borderSide: BorderSide(
                color: Theme.of(context).primaryColor,
                width: 2,
              ),
            ),
            border: OutlineInputBorder(
              borderRadius: BorderRadius.circular(30),
              borderSide: BorderSide(
                color: Theme.of(context).primaryColor,
                width: 3,
              ),
            ),
            prefixIcon: Padding(
              child: IconTheme(
                data: IconThemeData(color: Theme.of(context).primaryColor),
                child: icon,
              ),
              padding: EdgeInsets.only(left: 30, right: 10),
            )),
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

after creating our CustomTextField we can get data from it using the methode onSave and validated using the validator of every filed.

final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
  bool _autoValidate = false;
Enter fullscreen mode Exit fullscreen mode

the _formKey is very important for cheking the state of our form is validated or not .

  Form(
                  key: _formKey,
                  autovalidate: _autoValidate,
                  child: Column(
                    children: [
                      Container(
                        width: MediaQuery.of(context).size.width,
                        child: Column(
                          children: <Widget>[
                            new CustomTextField(
                              icon: Icon(Icons.email),
                              hint: "Email",
                              validator: (v) {
                                Pattern pattern = r'^(([^<>()[\]\\.,;:\s@\"]+'
                                    r'(\.[^<>()[\]\\.,;:\s@\"]+)*)|'
                                    r'(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.'
                                    r'[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)'
                                    r'+[a-zA-Z]{2,}))$';
                                RegExp regex = new RegExp(pattern);
                                if (v.length == 0) return "* require";
                                if (!regex.hasMatch(v))
                                  return 'Enter Valid Email';
                              },
                              onSaved: (newValue) => {
                                _email = newValue,
                                print("New value in email field $newValue"),
                              },
                            ),
                            // Input("Email", Icons.email, 10, emailController),
                            // InputPassword(passwordController, 32),
                            new CustomTextField(
                              icon: Icon(Icons.vpn_key),
                              hint: "Password",
                              obsecure: true,
                              validator: (v) {
                                if (v.length == 0) return "* require";
                                if (v.length < 2)
                                  return 'Password can\'t be less then 6 characteres  ';
                              },
                              onSaved: (newValue) => _password = newValue,
                            ),
                            forgotPassword,
                            SizedBox(
                              height: 25,
                            ),
                            Row(
                              crossAxisAlignment: CrossAxisAlignment.center,
                              mainAxisAlignment: MainAxisAlignment.spaceAround,
                              children: [
                                MyButton("sign in", 3, this.signIn),
                                MyButton("Sign up", 3, this.signUp),
                              ],
                            )
                          ],
                        ),
                      )
                    ],
                  ),
                ),
Enter fullscreen mode Exit fullscreen mode

the fonction for submit our form :
First we check if the form is validate

  bool validateForm() {
    if (!_formKey.currentState.validate()) {
      this.setState(() {
        _autoValidate = true;
      });
      return false;
    }
    return true;
  }
Enter fullscreen mode Exit fullscreen mode

we can use methode for crypting our password :

static String hashPass(String password) {
    var key = utf8.encode("pass@word/user*APP");
    var bytePass = utf8.encode(password);
    var hmacSha256 = new Hmac(sha256, key);
    var hashPass = hmacSha256.convert(bytePass);
    return hashPass.toString();
  }
Enter fullscreen mode Exit fullscreen mode

because when I am register the user I am using this methode
for crypting the password.

 void signIn() {
    final FormState form = _formKey.currentState;

    if (validateForm()) {
      form.save();
      print("$_email -- ${Util.hashPass(this._password)} \n");
      print("$_email -- $_password");
      String hashPassword = Util.hashPass(this._password);
      this.setState(() {
        isLoading = true;
      });
      controller.signIn(_email, hashPassword).then((value) => {
            print("Value retun from signIn methode : $value"),
            if (value == null)
              {
                this.setState(() {
                  isLoading = false;
                }),
                _scaffoldKey.currentState.showSnackBar(
                  SnackBar(
                    backgroundColor: Colors.white,
                    content: new ShowSnackBar(
                      color: Colors.red,
                      msg: "email or password are wrong",
                    ),
                  ),
                ),
              }
            else
              {
                userSession.saveSessionUser(value).then((value) => {
                      print("User saved in sharedRefrences"),
                      this.setState(() {
                        isLoading = false;
                      }),
                      print("User authentified"),
                      sleep(new Duration(milliseconds: 5)),
                      Navigator.push(
                          context, SlideRightRoute(page: ControllerScreens()))
                    }),
              }
          });
    }
  }
Enter fullscreen mode Exit fullscreen mode

Top comments (0)