Share
Flutter Mobile App. Development

Course Outline

Week 1
Week 2
Week 3
Week 4
Week 5
Week 6
Week 7
Week 8
Week 9
Week 10
Week 11
Week 12

FORM PROCESSING


  • Writing the PHP scripts for Processing the login and signing up form and the script for the logout for the socialize app
  • Writing the flutter main.dart for the socialize app
Week 13

SponsoredAdvertise

PROCESSING THE SIGN UP AND LOGIN FORM OF THE SOCIAL NETWORK APP


We will store the session token once a user signs up or login using shared preference.

Anytime the app communicates with the server, we will fetch the stored session token and pass it in a form which communicates with the server. The session token is unique and identifies the user communicating with the server.


Database


socialize


Database Tables


CREATE TABLE `users` (
  `name` text NOT NULL,
  `picture` text NOT NULL,
  `email` text NOT NULL,
  `password` text NOT NULL,
  `heartbeat` int(11) NOT NULL,
  `token` text NOT NULL,
  `date` date NOT NULL,
  `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `id` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `sessions` (
  `userid` int(11) NOT NULL,
  `session` text NOT NULL,
  `date` date NOT NULL,
  `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `id` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


Folder in htdocs in xampp


socialize


Php Files


db.php


fn = $fn;
	}
	/* Database Connectivity */
	function db_host(){
		return "localhost";
	}
	function db_username(){
		return "root";
	}
	function db_password(){
		return '';
	}
	function db_name(){
		return "socialize";
	}
	function db_connect(){
		$con = mysqli_connect($this->db_host(),$this->db_username(),$this->db_password(),$this->db_name());
		return $con;
	}
	function db_close($con){
		mysqli_close ($con);
	}
	/* GENERAL FUNCTIONS */
	function escape($con,$str){
		return mysqli_real_escape_string ($con ,$str);
	}
	function db_rows($con,$sql){
		$result = mysqli_query($con,$sql);
		$num_rows = mysqli_num_rows($result);
		return $num_rows;
	}
	function user_exist($email){
		$con = $this->db_connect();
		$sql = "select * from users where lower(email)=lower('".$this->escape($con,$email)."')";
		if($this->db_rows($con,$sql)>0){
			return true;
		}else{
			return false;
		}
	}
	function generate_session(){
		$con = $this->db_connect();
		$ok = 0;
		while($ok==0){
			$session = md5($this->fn->generate_token().time());
			$sql = "select * from sessions where session='".$this->escape($con,$session)."'";
			if($this->db_rows($con,$sql)==0){
				$ok=1;
			}
		}
		$this->db_close($con);
		return $session;
	}
	function signup($name,$email,$password){
		/* Generate unique token for each user */
		$token = md5($email.time());
		/* Connect to database */
		$con = $this->db_connect();
		$success = 0;
		$session = "";
		$sql = "insert into users(name,email,password,heartbeat,token,date) values
		(
		'".$this->escape($con,$name)."',
		'".$this->escape($con,strtolower($email))."',
		'".$this->fn->encrypt_password($password)."',
		".time().",
		'".$this->escape($con,strtolower($token))."',
		CURDATE()
		)
		";
		if(mysqli_query($con,$sql)){
			$success = 1;
			/* Generate and store session for user */
			$userid = mysqli_insert_id($con);
			$session = $this->generate_session();
			$sql = "insert into sessions(userid,session,date) values
			(
			".intval($userid).",
			'".$this->escape($con,$session)."',
			CURDATE()
			)
			";
			mysqli_query($con,$sql);
		}
		/* Close database */
		$this->db_close($con);
		$response = array();
		$response['success'] = $success;
		$response['session'] = $session;
		return $response;
	}
	function login($email,$password){
		/* Connect to database */
		$con = $this->db_connect();
		$success = 0;
		$session = "";
		$sql = "select * from users where lower(email)=lower('".$this->escape($con,$email)."') and password='".$this->fn->encrypt_password($password)."'";
		if($this->db_rows($con,$sql)>0){
			$success = 1;
			$query = mysqli_query($con,$sql);
			while($row=mysqli_fetch_array($query)){
				$userid = $row['id'];
			}
			/* Generate and store session for user */
			$session = $this->generate_session();
			$sql = "insert into sessions(userid,session,date) values
			(
			".intval($userid).",
			'".$this->escape($con,$session)."',
			CURDATE()
			)
			";
			mysqli_query($con,$sql);
		}
		/* Close database */
		$this->db_close($con);
		$response = array();
		$response['success'] = $success;
		$response['session'] = $session;
		return $response;
	}
	function session_exist($session){
		$con = $this->db_connect();
		$sql = "select * from sessions where session='".$this->escape($con,$session)."'";
		if($this->db_rows($con,$sql)>0){
			$this->db_close($con);
			return true;
		}else{
			$this->db_close($con);
			return false;
		}
	}
	function logout($session){
		$con = $this->db_connect();
		$sql = "delete from sessions where session='".$this->escape($con,$session)."'";
		if(mysqli_query($con,$sql)){
			$this->db_close($con);
			return true;
		}else{
			$this->db_close($con);
			return false;
		}
	}
}


For database functions


fn.php


=5){
			return true;
		}else{
			return false;
		}
	}
	function encrypt_password($password){
		return md5($password);
	}
	function generate_token() {
		$alphabet = "abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789";
		$pass = array();
		$alphaLength = strlen($alphabet) - 1; //put the length -1 in cache
		for ($i = 0; $i < 20; $i++) {
			$n = rand(0, $alphaLength);
			$pass[] = $alphabet[$n];
		}
		return implode($pass); //turn the array into a string
	}
}
?>


For general functions


signup.php


validate_email($email)){
	$message = "Please email is not in the correct format.";
}else if($db->user_exist($email)){
	$message = "This email has already been used. Login if account is yours.";
}else if(empty($password)){
	$message = "Please enter your password.";
}else if(!$fn->validate_password($password)){
	$message = "Please password is too weak. Password must be at least 5 characters long.";
}else{
	$signup = $db->signup($name,$email,$password);
	if($signup['success']==1){
		$success = 1;
		$session = $signup['session'];
		$message = "Account is successfully created.";
	}else{
		$message = "Server error. Please try again later.";
	}
}
/* Send json information */
echo json_encode(array("success"=>$success,"message"=>$message,"session"=>$session));
?>


For sign up


login.php


login($email,$password);
	if($login['success']==1){
		$success = 1;
		$session = $login['session'];
		$message = "Login is successfully.";
	}else{
		$message = "Incorrect login details.";
	}
}
/* Send json information */
echo json_encode(array("success"=>$success,"message"=>$message,"session"=>$session));
?>


For login


logout.php


session_exist($session))){
	if($db->logout($session)){
		$success = 1;
	}
}
/* Send json information */
echo json_encode(array("success"=>$success));
?>


For logout


As stated above, your above PHP scripts should be in your socialize folder in the htdocs in xampp folder


Flutter Files


pubspec.yaml


Your pubspec.yaml should look like this:


dependencies:
flutter:
sdk: flutter

http: ^0.12.0+2
shared_preferences: ^0.5.6
cupertino_icons: ^0.1.3

# The following section is specific to Flutter.
flutter:
assets:
- assets/logo.png
- assets/bg.jpg
# the material Icons class.
uses-material-design: true


main.dart


import 'package:flutter/material.dart';
import 'signup.dart';
import 'account.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Socialize',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Login'),
);
}
}

class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;

@override
_MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State {
bool show_login = false;
// For CircularProgressIndicator.
String session = "";
bool visible = false ;
final _formKey = GlobalKey();
final _scaffoldKey = GlobalKey();
// Getting value from TextField widget.
final emailController = TextEditingController();
final passwordController = TextEditingController();
//Check if shared token is set to redirect user to account page
@override
void initState() {
super.initState();
fetchSession();
}
fetchSession() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
session = (prefs.getString('session') ?? "");
if(!session.isEmpty){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Account())
);
}else{
setState(() {
show_login = true ;
});
}
}
Future login() async{
// Showing CircularProgressIndicator.
setState(() {
visible = true ;
});

String email = emailController.text;
String password = passwordController.text;
// SERVER SIGN UP API URL
var url = 'http://192.168.43.94/socialize/login.php';
// Store all data with Param Name.
var data = {'email': email, 'password': password};
// Starting Web API Call.
var response = await http.post(url, body: json.encode(data));
// Getting Server response into variable.
Mapdynamic> responseJson = jsonDecode(response.body);
var message = responseJson['message'];
var success = responseJson['success'];
var session = responseJson['session'];
//If account is successfully created, set session shared preference and redirect to account page
if(success==1){
//Set animation progress to invisible
setState(() {
visible = false ;
});
_scaffoldKey.currentState.showSnackBar(SnackBar(content: Text(message)));
setSession(session);
}else{
//Show response from the server
_scaffoldKey.currentState.showSnackBar(SnackBar(content: Text(message)));
//Set animation progress to invisible
setState(() {
visible = false ;
});
}
}
Future setSession(String session) async{
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('session', session);
//Redirect to account page
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Account())
);
}
@override
Widget build(BuildContext context) {
if(show_login) {
return Scaffold(
key: _scaffoldKey,
body: Stack(
children: [
Container(
decoration: new BoxDecoration(
image: new DecorationImage(
fit: BoxFit.cover,
image: AssetImage("assets/bg.jpg"), //Background image
)),
),
Center(
child: SingleChildScrollView(
padding: EdgeInsets.all(30.0),
child: Form(
key: _formKey,
child: Column(
children: [
SizedBox(
height: 60.0,
),
SizedBox(
height: 70.0,
child: Image.asset(
"assets/logo.png",
fit: BoxFit.contain,
),
),
SizedBox(
height: 60.0,
),
TextFormField(
controller: emailController,
keyboardType: TextInputType.emailAddress,
// The validator receives the text that the user has entered.
validator: (value) {
if (value.isEmpty) {
return 'Please enter your email';
}
return null;
},
decoration: InputDecoration(
prefixIcon: Icon(
Icons.email,
color: Colors.white,
),
hintStyle: TextStyle(color: Colors.white),
filled: true,
fillColor: Colors.black45,
hintText: 'Email',
border:
OutlineInputBorder(borderRadius: BorderRadius
.circular(30.0))
),
),
SizedBox(
height: 10.0,
),
TextFormField(
obscureText: true,
controller: passwordController,
// The validator receives the text that the user has entered.
validator: (value) {
if (value.isEmpty) {
return 'Please enter your password';
}
return null;
},
decoration: InputDecoration(
filled: true,
prefixIcon: Icon(Icons.lock, color: Colors.white),
hintStyle: TextStyle(color: Colors.white),
fillColor: Colors.black45,
hintText: 'Password',
border:
OutlineInputBorder(borderRadius: BorderRadius
.circular(30.0))
),
),
SizedBox(
height: 15.0,
),
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
FlatButton(
onPressed: () {},
child: Text(
'Forgot your Password?',
style: TextStyle(color: Colors.lightBlueAccent),
)),
SizedBox(
height: 15.0,
),
RaisedButton(
onPressed: () {
// Validate returns true if the form is valid, otherwise false.
if (_formKey.currentState.validate()) {
//Process form
login();
}
},
child: Padding(
padding: EdgeInsets.all(15.0),
child: Text('LOGIN')),
color: Colors.redAccent,
textColor: Colors.white,
),
],
),
SizedBox(
child: Visibility(
visible: visible,
child: Container(
margin: EdgeInsets.only(top: 10),
child: SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator()
),
)
),
),
SizedBox(
height: 40.0,
),
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Row(
children: [
Expanded(
child: Divider(
color: Colors.black,
height: 8.0,
),
),
SizedBox(
width: 8.0,
),
Text(
'OR',
style: TextStyle(color: Colors.black),
),
SizedBox(
width: 8.0,
),
Expanded(
child: Divider(
color: Colors.black,
height: 8.0,
),
)
],
),
],
),
SizedBox(
height: 40.0,
),
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// TODO Social Icons
RaisedButton(
onPressed: () {
// Load the sign up page.
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Signup())
);
},
child: Padding(
padding: EdgeInsets.all(15.0),
child: Text('SIGN UP')),
color: Colors.blue,
textColor: Colors.white,
),
],
),
],
),
),
),
),
],
),
);
}else{
//If we are still waiting for shared preference value to know if user is logged or not, show a loading animation
return Scaffold(
body:
Center(
child: new Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator()
),
],
),
),
),
);
}
}
}


NOTE


var url = 'http://192.168.43.94/socialize/login.php';


Use your ip address instead if you are using physical phone for testing. Your phone must be in the same network as your computer. Thus they must be connected to the same wireless network. If you are using your phone for the internet, it means your computer internet source must be from the phone by connecting the computer to the phone's wireless network through hotspot.


To determine your ip address, open the command prompt and run ipconfig.


Image


Figure: ipconfig command 

As you already know from week 1, to open the command prompt window, you can search cmd in the search bar for searching apps on the computer.

If you are using virtual device for the testing of your app, you can change the ip address to localhost since your testing device (virtual device) is on the machine where the server is located. Thus:


var url = 'http://localhost/socialize/login.php';


The login page


Login page

SponsoredAdvertise