Login using firebase and flutter

abdelouahedd

Abdelouahedd

Posted on June 18, 2020

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
💖 💪 🙅 🚩
abdelouahedd
Abdelouahedd

Posted on June 18, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Login using firebase and flutter
googlecloud Login using firebase and flutter

June 18, 2020