Hi Guys, Welcome to Proto Coders Point. In this flutter tutorial we will learn how to keep user logged in flutter using hive database example.
In This Flutter Tutorial, We will create a real-time login & registration in flutter app using backend as phpmyadmin sql server, so user can registration & do login process.
After login success, we will store login user details in Hive database using which we can keep user logged in flutter app so then whenever user re-visit the app again he will directly get logged in & Navigate to HomePage or Dashboard Page.
Let’s Get Started
Server Side – Backend Setup
phpmyadmin (database)
In my database, I have created a table by name “registered”, In the table there are 5 field i.e. id, name, email, phone, password. In registered table all our users data will get stored from flutter app.
PHP API SCRIPT – To get and store data to server database
1. Connection to my database server
connect.php
<?php //replace username with your phpmyadmin username //replace password with your phpmyadmin password // replacce database name with your database name $conn = mysqli_connect("localhost", "username", "password", "databasename"); if($conn) { //echo "Connection Success"; } else { //echo "Connection Failed"; } ?>
The above code is used to get connected to phomyadmin database.
2. Inserting data into our registered database table
registration.php
<?php $name = $_POST["name"]; $email= $_POST["email"]; $phone= $_POST["phone"]; $password = $_POST["password"]; require_once 'connect.php'; $findexist="select * from registered where phone='$phone'"; $resultsearch=mysqli_query($conn,$findexist); if(mysqli_num_rows($resultsearch)>0) { while($row=mysqli_fetch_array($resultsearch)) { $result["success"] = "3"; $result["message"] = "user Already exist"; echo json_encode($result); mysqli_close($conn); } } else{ $sql = "INSERT INTO registered (name,email,phone,password) VALUES ('$name','$email','$phone','$password');"; if ( mysqli_query($conn, $sql) ) { $result["success"] = "1"; $result["message"] = "Registration success"; echo json_encode($result); mysqli_close($conn); } else { $result["success"] = "0"; $result["message"] = "error in Registration"; echo json_encode($result); mysqli_close($conn); } } ?>
The registration.php code will help us in registrating user in our database.
From our flutter app registration page, we will send user data to registration.php file server side, the will help us to store/register use in database.
In above code, we have 2 query,
1st Query, will check if same user data is present is database, if user data exist then php code will send response as ‘success’ code as ‘3’ means ‘user exist’.
2nd Query, will insert user data in our database, if user do not exist then insert the user data in database table and send response as ‘success’ code as ‘1’ means ‘registration success’.
Login user – php code
login.php
<?php ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); $email= $_POST["email"]; $password = $_POST["password"]; require_once 'connect.php'; $list=""; $query="select * from registered where email='$email' AND password='$password'"; $result=mysqli_query($conn,$query); if(mysqli_num_rows($result)>0) { while($row=mysqli_fetch_array($result)) { if($list=="") { $id=$row['id']; $name=$row['name']; $email=$row['email']; $phone=$row['phone']; } } } if(mysqli_num_rows($result)==0) { $response["success"] = "0"; $response["message"]="user is not Registered, Please Register"; echo json_encode($response); mysqli_close($conn); } else { $response["success"]="1"; $response["message"]="Logged in successful"; $response["id"]=$id; $response["name"]=$name; $response["email"]=$email; $response["phone"]=$phone; echo json_encode($response); mysqli_close($conn); } ?>
The Login.php code will help user to login into flutter app.
From our flutter app we will send 2 parameter (i.e. Email & password) to login.php code.
The above login.php code, will run a query select all the details of a user, if user exist in registrated table, we will store user data in a var $response which is of kind json format & send the response back to flutter app.
Hosting the PHP Script Code in my hosting Provider
I have hosting in Hostinger.com.
So, This php Codes are on my WebHosting Provider Directory, which i can access by using domain name & the path to the php files.
Eg: https://protocoderspoint.com/php/registration.php
So, Now we are done with server side setup, Therefore now our php script is ready to get data from our flutter app.
Now Let’s check out how to send data from flutter app to php script to insert data into database for registration & then login & keep user logged in app.
Flutter Side – Coding – Snippet
Complete Source Code will be below at the end, Here you will get only the important snippet code.
Library Used – http, Hive, Hive_Flutter
http: To make network http calls, to send & retrive network response data.
hive: hive nosql local database, used to keep all the data of a user and keep user signed in.
hive_flutter: hive support in flutter framework.
User Registration – Snippet Code
Future Registration() async{ var regAPIUrl = "https://protocoderspoint.com/php/registration.php"; Map maped = { 'name':_name.text, 'email':_email.text, 'phone': _phone.text, 'password':_pass.text }; http.Response response = await http.post(Uri.parse(regAPIUrl),body: maped); var data = jsonDecode(response.body); print("Data: ${data}"); }
In Registration process, We are asking the user to input his/her name, email, phone, password.
TextEditingController is been attached as a controller to TextField to retrive text entered in it.
The above, Registration Method will be called when user enters all the details in form and click on register button.
In Registration() method, We have:
- A URL Path to registration.php.
- Map all the user enter data in key-value pair map object.
- http.post(url,body): using post method send data to server.
- http.Response get response from php file.
Therefore, registration() will send all the data to php code to insert data into database table.
User login – snippet Code
void login() async { var regAPIUrl = "https://protocoderspoint.com/php/login.php"; Map maped = { 'email':email.text, 'password':pass.text, }; http.Response response = await http.post(Uri.parse(regAPIUrl),body: maped); var data = jsonDecode(response.body); //after successful login, save user data in hive DB. if(data['success']=='1'){ if(isChecked){ box1.put('email', email.value.text); box1.put('pass', pass.value.text); } box1.put('WelPage_name', data['name']); box1.put('WelPage_email', data['email']); box1.put('WelPage_phone', data['phone']); box1.put('isLogged',true); Navigator.pushReplacement(context, MaterialPageRoute(builder: (builder)=>WelcomePage())); } }
In Login Process, As usual we ask user to enter his login credential i.e. email & password.
TextEditingController is been attached as a controller to TextField to retrive text entered in it.
In above login() method we have:
- A URL path to login.php file.
- Map all the user enter login credential in key-value pair map object.
- http.post to send login credential to login.php from authentication.
- http.Response to get response from login.php, The response will hold all the details of user such as name, phone, email that we can store in hive database.
Here after successful login, Save all the response from server in HIVE Database & navigate user to WelcomePage or DashboardPage.
Hive DB initialize & Open Hive Box
learn more on Hive Db Basic in flutter.
void main() async{ await Hive.initFlutter(); runApp(const MyApp()); }
@override void initState() { // TODO: implement initState super.initState(); createOpenBox(); }
late Box box1; void createOpenBox() async{ box1 = await Hive.openBox('logindata'); }
How to Keep user logged In Flutter
As you can see in above login() method after successful login, we are storing user data in hive database, with that we also put a key-value i.e.
box1.put('isLogged',true);
- isLogged : true : Means a user is logged In.
- isLogged : false: Means the user is LoggedOut from app.
Depending on this value, when user re-visit the app, if isLogged = true, we navigate the user direct to dashboard page else user will be sent to login page.
Complete Source Code – Flutter keep user logged in using hive database example
Flutter login registration UI design with hive database to keep user logged in, so that there is no need to sign in again an again.
main.dart
import 'package:flutter/material.dart'; import 'package:login_ui/welcome.dart'; import 'login_page.dart'; import 'package:hive/hive.dart'; import 'package:hive_flutter/hive_flutter.dart'; late Box box1; //init hive db and open the HIVE box void main() async{ await Hive.initFlutter(); box1 = await Hive.openBox('logindata');//init hive runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({Key? key}) : super(key: key); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', debugShowCheckedModeBanner: false, theme: ThemeData( primarySwatch: Colors.blue, ), //if islogged is true take user direct to WelcomePage else loginPage home: box1.get('isLogged',defaultValue: false)?WelcomePage():Login_Page() // load login page ); } }
registration.dart
import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:login_ui/login_page.dart'; import 'package:velocity_x/velocity_x.dart'; import 'package:http/http.dart' as http; class registrationpage extends StatefulWidget { const registrationpage({Key? key}) : super(key: key); @override _registrationpageState createState() => _registrationpageState(); } class _registrationpageState extends State<registrationpage> { TextEditingController _name = TextEditingController(); TextEditingController _email = TextEditingController(); TextEditingController _phone = TextEditingController(); TextEditingController _pass = TextEditingController(); @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: Stack( children: [ Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage("images/assets/backgroundUI.png"), fit: BoxFit.cover ) ), ), Padding( padding: const EdgeInsets.fromLTRB(20,40 , 20, 0), child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ Container( height: 100, width: 100, child: SvgPicture.asset("images/assets/xing.svg")), HeightBox(10), "Registration".text.color(Colors.white).size(20).make(), HeightBox( 20 ), Padding( padding: const EdgeInsets.fromLTRB(30, 0, 30, 0), child: TextField( controller: _name, decoration: InputDecoration( hintText: 'Full Name', hintStyle: TextStyle(color: Colors.white), enabledBorder: OutlineInputBorder( borderRadius: new BorderRadius.circular(10.0), borderSide: BorderSide( color: Colors.white ), ), focusedBorder: OutlineInputBorder( borderRadius: new BorderRadius.circular(10.0), borderSide: BorderSide( color: Colors.blue ) ), isDense: true, // Added this contentPadding: EdgeInsets.fromLTRB(10, 20, 10, 10), ), cursorColor: Colors.white, style: TextStyle(color: Colors.white), ), ), HeightBox( 20 ), Padding( padding: const EdgeInsets.fromLTRB(30, 0, 30, 0), child: TextField( controller: _email, decoration: InputDecoration( hintText: 'Enter Email', hintStyle: TextStyle(color: Colors.white), enabledBorder: OutlineInputBorder( borderRadius: new BorderRadius.circular(10.0), borderSide: BorderSide( color: Colors.white ), ), focusedBorder: OutlineInputBorder( borderRadius: new BorderRadius.circular(10.0), borderSide: BorderSide( color: Colors.blue ) ), isDense: true, // Added this contentPadding: EdgeInsets.fromLTRB(10, 20, 10, 10), ), cursorColor: Colors.white, style: TextStyle(color: Colors.white), ), ), HeightBox( 20 ), Padding( padding: const EdgeInsets.fromLTRB(30, 0, 30, 0), child: TextField( controller: _phone, decoration: InputDecoration( hintText: 'Phone Number', hintStyle: TextStyle(color: Colors.white), enabledBorder: OutlineInputBorder( borderRadius: new BorderRadius.circular(10.0), borderSide: BorderSide( color: Colors.white ), ), focusedBorder: OutlineInputBorder( borderRadius: new BorderRadius.circular(10.0), borderSide: BorderSide( color: Colors.blue ) ), isDense: true, // Added this contentPadding: EdgeInsets.fromLTRB(10, 20, 10, 10), ), cursorColor: Colors.white, style: TextStyle(color: Colors.white), ), ), HeightBox( 20 ), Padding( padding: const EdgeInsets.fromLTRB(30, 0, 30, 0), child: TextField( controller: _pass, decoration: InputDecoration( hintText: 'Password', hintStyle: TextStyle(color: Colors.white), enabledBorder: OutlineInputBorder( borderRadius: new BorderRadius.circular(10.0), borderSide: BorderSide( color: Colors.white ), ), focusedBorder: OutlineInputBorder( borderRadius: new BorderRadius.circular(10.0), borderSide: BorderSide( color: Colors.blue ) ), isDense: true, // Added this contentPadding: EdgeInsets.fromLTRB(10, 20, 10, 10), ), cursorColor: Colors.white, style: TextStyle(color: Colors.white), ), ), HeightBox(20), GestureDetector( onTap:(){ Registration(); }, child: "Sign-Up".text.white.light.xl.makeCentered().box.white.shadowOutline(outlineColor: Colors.grey).color(Color(0XFFFF0772)).roundedLg.make().w(150).h(40)), HeightBox(140), ], ), ), ) ], ), ), bottomNavigationBar: GestureDetector( onTap: (){ Navigator.pushReplacement(context, MaterialPageRoute(builder: (context)=>Login_Page())); }, child: RichText(text: TextSpan( text: 'New User?', style: TextStyle(fontSize: 15.0, color: Colors.black), children: <TextSpan>[ TextSpan( text: ' Login Now', style: TextStyle( fontWeight: FontWeight.w600, fontSize: 18, color: Color(0XFF4321F5)), ), ], ) ).pLTRB(20, 0, 0, 15), ) ); } Future Registration() async{ var regAPIUrl = "https://protocoderspoint.com/php/registration.php"; Map maped = { 'name':_name.text, 'email':_email.text, 'phone': _phone.text, 'password':_pass.text }; http.Response response = await http.post(Uri.parse(regAPIUrl),body: maped); var data = jsonDecode(response.body); print("Data: ${data}"); } }
login_page.dart
import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:login_ui/registrationpage.dart'; import 'package:login_ui/welcome.dart'; import 'package:velocity_x/velocity_x.dart'; import 'package:hive/hive.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:http/http.dart' as http; class Login_Page extends StatefulWidget { const Login_Page({Key? key}) : super(key: key); @override _Login_PageState createState() => _Login_PageState(); } class _Login_PageState extends State<Login_Page> { bool isChecked = false; TextEditingController email = TextEditingController(); TextEditingController pass = TextEditingController(); late Box box1; @override void initState() { // TODO: implement initState super.initState(); createBox(); } void createBox()async{ box1 = await Hive.openBox('logindata'); getdata(); } void getdata()async{ if(box1.get('email')!=null){ email.text = box1.get('email'); isChecked = true; setState(() { }); } if(box1.get('pass')!=null){ pass.text = box1.get('pass'); isChecked = true; setState(() { }); } } @override Widget build(BuildContext context) { return Scaffold( resizeToAvoidBottomInset: false, body: SafeArea( child: Stack( children: [ Container( decoration: const BoxDecoration( image: DecorationImage( image: AssetImage("images/assets/backgroundUI.png"), fit: BoxFit.cover)), ), Padding( padding: const EdgeInsets.fromLTRB(20, 40, 20, 0), child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ Container( height: 100, width: 100, child: SvgPicture.asset("images/assets/xing.svg")), const HeightBox(10), "Login".text.color(Colors.white).size(20).make(), const HeightBox(20), Padding( padding: const EdgeInsets.fromLTRB(30, 0, 30, 0), child: TextField( controller: email, decoration: InputDecoration( hintText: 'Email', hintStyle: const TextStyle(color: Colors.white), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10.0), borderSide: const BorderSide(color: Colors.white), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10.0), borderSide: const BorderSide(color: Colors.blue)), isDense: true, // Added this contentPadding: const EdgeInsets.fromLTRB(10, 20, 10, 10), ), cursorColor: Colors.white, style: const TextStyle(color: Colors.white), ), ), const HeightBox(20), Padding( padding: const EdgeInsets.fromLTRB(30, 0, 30, 0), child: TextField( controller: pass, obscureText:true, decoration: InputDecoration( hintText: 'Password', hintStyle: const TextStyle(color: Colors.white), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10.0), borderSide: const BorderSide(color: Colors.white), ), focusedBorder: OutlineInputBorder( borderRadius: new BorderRadius.circular(10.0), borderSide: const BorderSide(color: Colors.blue)), isDense: true, // Added this contentPadding: const EdgeInsets.fromLTRB(10, 20, 10, 10), ), cursorColor: Colors.white, style: const TextStyle(color: Colors.white), ), ), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text("Remember Me",style: TextStyle(color: Colors.white),), Checkbox( value: isChecked, onChanged: (value){ isChecked = !isChecked; setState(() { }); }, ), ], ), GestureDetector( onTap: () {}, child: const Text( "Forgot Password ? Reset Now", style: TextStyle(color: Colors.white), ), ), HeightBox(10), GestureDetector( onTap: () { print("Login Clicked Event"); login(); }, child: "Login".text.white.light.xl.makeCentered().box.white.shadowOutline(outlineColor: Colors.grey).color(Color(0XFFFF0772)).roundedLg.make().w(150).h(40)), const HeightBox(20), ], ), ) ], ), ), bottomNavigationBar: GestureDetector( onTap: () { Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => registrationpage())); }, child: RichText( text: const TextSpan( text: 'New User?', style: TextStyle(fontSize: 15.0, color: Colors.black), children: <TextSpan>[ TextSpan( text: ' Register Now', style: TextStyle( fontWeight: FontWeight.w600, fontSize: 18, color: Color(0XFF4321F5)), ), ], )).pLTRB(20, 0, 0, 15), )); } void login() async { var regAPIUrl = "https://protocoderspoint.com/php/login.php"; Map maped = { 'email':email.text, 'password':pass.text, }; http.Response response = await http.post(Uri.parse(regAPIUrl),body: maped); var data = jsonDecode(response.body); //after successful login, save user data in hive DB. if(data['success']=='1'){ if(isChecked){ box1.put('email', email.value.text); box1.put('pass', pass.value.text); } box1.put('WelPage_name', data['name']); box1.put('WelPage_email', data['email']); box1.put('WelPage_phone', data['phone']); box1.put('isLogged',true); Navigator.pushReplacement(context, MaterialPageRoute(builder: (builder)=>WelcomePage())); } } }
welcome.dart
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive/hive.dart'; import 'package:login_ui/login_page.dart'; class WelcomePage extends StatefulWidget { const WelcomePage({Key? key}) : super(key: key); @override _WelcomePageState createState() => _WelcomePageState(); } class _WelcomePageState extends State<WelcomePage> { Box? box1; @override void initState() { // TODO: implement initState super.initState(); OpenBox(); } void OpenBox() async{ box1 = await Hive.openBox('logindata'); setState(() { }); } @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ //show signed in user data Text('Name: ${box1?.get('WelPage_name')}'), Text('Email: ${box1?.get('WelPage_email')}'), Text('Phone No: ${box1?.get('WelPage_phone')}'), //logged out delete all the data from hive db ElevatedButton(onPressed: (){ box1?.put('isLogged',false); box1?.delete('WelPage_name'); box1?.delete('WelPage_email'); box1?.delete('WelPage_phone'); Navigator.pushReplacement(context, MaterialPageRoute(builder: (builder)=>Login_Page())); }, child: const Text('LogOut')) ], ), ) ); } }