flutter keep user logged in using hive database
flutter keep user logged in using hive database

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

Video Tutorial

x
Flutter Keep User Logged In - Hive Database Example - Realtime login, registration example
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.

phpmyadmin

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'))
          ],
        ),
      )
    );
  }
}