Home Screen and Login
🏠 Home Screen and Login
🔒 Authentication and Login
https://github.com/sumithpdd/flutterworkshop/tree/03_setup_firebase
Lets first add login screen for that we need to call auth service
,
We create or use 📁 Folder = > services -> File -> auth_service.dart
we are adding FirebaseMessaging for token reference, not an important step
import 'package:firebase_auth/firebase_auth.dart';import 'package:firebase_messaging/firebase_messaging.dart';import 'package:flutter/services.dart';class AuthService {final FirebaseAuth _auth = FirebaseAuth.instance;final FirebaseMessaging _messaging = FirebaseMessaging.instance;Stream<User?> get user => _auth.authStateChanges();Future<void> signup(String name, String email, String password) async {try {var authResult = await _auth.createUserWithEmailAndPassword(email: email,password: password,);if (authResult.user != null) {}} on PlatformException {rethrow;}}Future<void> login(String email, String password) async {try {await _auth.signInWithEmailAndPassword(email: email, password: password);} on PlatformException {rethrow;}}Future<void> logout() async {Future.wait([_auth.signOut(),]);}}
This user should also be stored in a database, so that we can use it in chat.
Create a constants.dart
📄 file under helpers
📁 folder
import 'package:cloud_firestore/cloud_firestore.dart';import 'package:firebase_storage/firebase_storage.dart';final FirebaseFirestore _db = FirebaseFirestore.instance;final usersRef = _db.collection('users');final chatsRef = _db.collection('chats');final FirebaseStorage _storage = FirebaseStorage.instance;final storageRef = _storage.ref();
go back and update auth_service.dart
📄 file and import
import 'package:/helpers/constants.dart';
if (authResult.user != null) {+ String? token = await _messaging.getToken();+ usersRef.doc(authResult.user!.uid).set({+ 'name': name,+ 'email': email,+ 'profileImageUrl': '',+ 'bio': '',+ 'token': token,+ });}
Full code.=> https://github.com/sumithpdd/gdg_flutter_firebase_chat/blob/Authentication/lib/services/auth_service.dart
Create a new 📄 file app_user.dart
under models
📁 folder to match these fields and map data from the database.
FYI : understand this piece of codeimport 'package:cloud_firestore/cloud_firestore.dart';class AppUser {final String? id;final String? name;final String? profileImageUrl, email, bio, token;// {} named parametersAppUser({this.id,this.name,this.profileImageUrl,this.email,this.bio,this.token});factory AppUser.fromDoc(DocumentSnapshot doc) {return AppUser(id: doc.id,name: doc['name'],profileImageUrl: doc['profileImageUrl'],email: doc['email'],bio: doc['bio'],token: doc['token']);}}
....// {} named parametersUser({this.id, this.name, this.email, this.token});....factory User.fromDoc(DocumentSnapshot doc)
Check firebase Console
Make sure database and authentication is set
Step 2 - Login and Signup Screen
To check if authentication is working , We create a new screen for Login and Signup
📁 Folder => screens
- > 📄 file=> login_screen.dart
Code from login screen->
import 'package:flutter/material.dart';import 'package:flutter/services.dart';import 'package:devfest_flutter_firebase_chat/helpers/app_constants.dart';import 'package:devfest_flutter_firebase_chat/services/auth_service.dart';class LoginScreen extends StatefulWidget {static const String id = 'login_screen';const LoginScreen({Key? key}) : super(key: key);@override_LoginScreenState createState() => _LoginScreenState();}class _LoginScreenState extends State<LoginScreen> {final _loginFormKey = GlobalKey<FormState>();final _signupFormKey = GlobalKey<FormState>();late String _name, _email, _password;int _selectedIndex = 0;_buildLoginForm() {return Form(key: _loginFormKey,child: Column(children: <Widget>[_buildEmailTF(),_buildPasswordTF(),]),);}_buildSignupForm() {return Form(key: _signupFormKey,child: Column(children: <Widget>[_buildNameTF(),_buildEmailTF(),_buildPasswordTF(),]),);}_buildNameTF() {return Padding(padding: const EdgeInsets.symmetric(horizontal: 30.0, vertical: 10.0),child: TextFormField(decoration: const InputDecoration(labelText: 'Name', icon: Icon(Icons.person_sharp)),validator: (input) =>input!.trim().isEmpty ? 'Please enter a vaild name' : null,onSaved: (input) => _name = input!.trim(),),);}_buildEmailTF() {return Padding(padding: const EdgeInsets.symmetric(horizontal: 30.0, vertical: 10.0),child: TextFormField(decoration: const InputDecoration(labelText: 'Email', icon: Icon(Icons.email_sharp)),validator: (input) =>!input!.contains('@') ? 'Please enter a vaild email' : null,onSaved: (input) => _email = input!,),);}_buildPasswordTF() {return Padding(padding: const EdgeInsets.symmetric(horizontal: 30.0, vertical: 10.0),child: TextFormField(decoration: const InputDecoration(labelText: 'Password', icon: Icon(Icons.lock_open_sharp)),validator: (input) =>input!.length < 6 ? 'Password must be atleast 6 characters' : null,onSaved: (input) => _password = input!,obscureText: true,),);}_submit() async {try {if (_selectedIndex == 0 && _loginFormKey.currentState!.validate()) {_loginFormKey.currentState!.save();await authservice.login(_email, _password);} else if (_selectedIndex == 1 &&_signupFormKey.currentState!.validate()) {_signupFormKey.currentState!.save();await authservice.signup(_name, _email, _password);}} on PlatformException catch (error) {_showErrorDialog(error.message!);}}// _changeLanguage() async {// I18n.onLocaleChanged(const Locale("da", "DK"));// }_showErrorDialog(String errorMessage) {showDialog(context: context,builder: (_) {return AlertDialog(title: const Text('Error'),content: Text(errorMessage),actions: <Widget>[TextButton(onPressed: () => Navigator.pop(context),child: const Text('OK'))],);},);}final AuthService authservice = AuthService();@overrideWidget build(BuildContext context) {return Scaffold(resizeToAvoidBottomInset: false,body: Column(children: [Padding(padding: const EdgeInsets.only(left: 8.0, top: 30.0),child: Card(semanticContainer: true,clipBehavior: Clip.antiAliasWithSaveLayer,child: Column(crossAxisAlignment: CrossAxisAlignment.center,children: [Image.asset("assets/images/devfest_uki.gif",),Padding(padding: EdgeInsets.all(8.0),child: Text(" { devfest - 2021 - chat app }",style: TextStyle(backgroundColor: AppConstants.hexToColor(AppConstants.APP_PRIMARY_COLOR_BLACK),color: AppConstants.hexToColor(AppConstants.APP_PRIMARY_COLOR_LIGHT),fontSize: 24,fontWeight: FontWeight.w600,),),),]),shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0),),elevation: 5,margin: EdgeInsets.all(10),),),const SizedBox(height: 10.0),Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[//18n.of(context).welcome,Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: <Widget>[SizedBox(width: 150.0,child: FlatButton(shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0),),color: _selectedIndex == 0? AppConstants.hexToColor(AppConstants.APP_PRIMARY_COLOR): AppConstants.hexToColor(AppConstants.APP_BACKGROUND_COLOR_GRAY),child: Text('Login',style: TextStyle(fontSize: 20.0,color: _selectedIndex == 0? AppConstants.hexToColor(AppConstants.APP_PRIMARY_FONT_COLOR_WHITE): AppConstants.hexToColor(AppConstants.APP_PRIMARY_COLOR)),),onPressed: () => setState(() => _selectedIndex = 0),),),SizedBox(width: 150.0,child: FlatButton(shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0),),color: _selectedIndex == 1? AppConstants.hexToColor(AppConstants.APP_PRIMARY_COLOR): AppConstants.hexToColor(AppConstants.APP_BACKGROUND_COLOR_GRAY),child: Text('Sign Up',style: TextStyle(fontSize: 20.0,color: _selectedIndex == 1? AppConstants.hexToColor(AppConstants.APP_PRIMARY_FONT_COLOR_WHITE): AppConstants.hexToColor(AppConstants.APP_PRIMARY_COLOR)),),onPressed: () => setState(() => _selectedIndex = 1),),)],),_selectedIndex == 0 ? _buildLoginForm() : _buildSignupForm(),const SizedBox(height: 20.0),SizedBox(width: 180,child: FlatButton(shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),color: AppConstants.hexToColor(AppConstants.APP_PRIMARY_COLOR),onPressed: _submit,child: Text('Submit',style: TextStyle(color: AppConstants.hexToColor(AppConstants.APP_PRIMARY_FONT_COLOR_WHITE),fontSize: 20.0,),),)),],),),],),);}}
Update Main.dart
Initialize Firebase on start
Delete class `MyHomePage` and direct home to the new `LoginScreen`.void main() async {+ WidgetsFlutterBinding.ensureInitialized();+ await Firebase.initializeApp();
home: const LoginScreen(),