Flutter Chat App using Firebase location sharing.
Task 5 — Flutter App Development (LW)
Description:
1) Create a chat app representing beautiful UI
2)store/retrieve user data into firebase
3) Integrate the app with map API
4)prompt the current location of your friend on Google maps of the user on click of the Button.
This blog will guide you on how to develop high performing chat app with Geo location sharing in Flutter with Firebase in simple steps…
Let’s begin with the essential points
4 Major Steps to Develop Chat App in Flutter With Firebase
- Firebase Authorization: Sign in, Sign up or Sing Out
- Firebase Firestore for Installing Plugins: Upload, Remove and Retrieve Data Stored in Cloud Firestore
- Creating the Layout of the Chat App Screen
- Final Linking of the Flutter Chat App with Firebase
- Adding Geolocation sharing.
Before moving on Further first let's understand the firestore storage.
What is Cloud Firestore?
Cloud Firestore is a flexible, scalable database for mobile, web, and server development from Firebase and Google Cloud Platform. Like Firebase Realtime Database, it keeps your data in-sync across client apps through realtime listeners and offers offline support for mobile and web so you can build responsive apps that work regardless of network latency or Internet connectivity. Cloud Firestore also offers seamless integration with other Firebase and Google Cloud Platform products, including Cloud Functions.
Firestore Database consists of 3 things
- Collections — Collections are nothing but a set of documents.
- Documents — Documents are set of sub-collections and fields.
- Fields — Field consists of attributes and values. The values are of the type of string, number, Boolean, map, array, null, timestamp, geopoints, and reference.
- If you observe the building blocks of Firestore you can find that it is similar to JSON structure where you can store data in any form, any structure, and any depth.
Any complex feature can be implemented easily with proper model design. In this article, we will learn how to define and implement model both abstract and specific for programming language
Basic user flow of our chat app.
Now let's get started:
Step 0 : Setting up the Basic architecture of the app for an easier development process.
Open the pubspec.yaml file in your project and add the following dependencies into it.
firebase_core: "0.5.0"
shared_preferences: ^0.5.12 // To store the login state of the user
simple_animations: ^1.3.3 //(optional) for Fade in animation
firebase_auth: ^0.18.1+1 //for firebase authentication
google_sign_in: "^4.5.1" //for google signin functionality
geolocator: ^5.3.2+2 // for accessing user geolocation
google_maps_flutter: ^0.5.30 // google map integration
1️⃣ create all the screens in a single folder named as a view with the different names as:
- Singin.dart
- Singup.dart
- Home.dart(Home page to display active conversations).
- Conversation_screen.dart
- map.dart // for displaying the map
- search.dart // user search screen
2️⃣create the following file in a single folder named as Services with the different names as These files will include the file which deals with authentication and database services.
- Auth.dart
- database.dart
3️⃣create the following file in a single folder named as a helper with the different names. This folder will include the files which deal with Helping functions // Don’t panic we will understand the use of each and every file further.
- Helper.dart // Shared preference Will allow us to Save so info like login status and logged in Username and email to store in the phone memory.
import 'package:shared_preferences/shared_preferences.dart';import 'package:flutter/material.dart';class HelperFunction {
static String sharedPreferencesUserLoggedInKey = "ISLOGGEDIN";
static String sharedPreferencesUserNameKey = "USERNAMEKEY";
static String sharedPreferencesUserEmailKey = "USEREMAILKEY";static Future<void> saveuserLoggedInSharedPreference(
bool isUserLoggedIn) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return await prefs.setBool(
sharedPreferencesUserLoggedInKey, isUserLoggedIn);
}
static Future<void> saveuserNameSharedPreference(String userName) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return await prefs.setString(sharedPreferencesUserNameKey, userName);
}
static Future<void> saveuserEmailSharedPreference(String userEmail) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return await prefs.setString(sharedPreferencesUserEmailKey, userEmail);
}
//getting the data form shared preferences
static Future<bool> GetuserLoggedInSharedPreference() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getBool(sharedPreferencesUserLoggedInKey);
}
static Future<String> getuserNameSharedPreference() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getString(sharedPreferencesUserNameKey);
}
static Future<String> getuserEmailSharedPreference() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getString(sharedPreferencesUserEmailKey);
}
}
- authenticate.dart // This file will help the user to choose to signup or sign in with will be the base file which will redirect the user to a different scaffold for signup and sign in.
import 'package:flutter/material.dart';
class Authenticate extends StatefulWidget {
@override
_AuthenticateState createState() => _AuthenticateState();
}
class _AuthenticateState extends State<Authenticate> {
bool showlogin = true;
@override
Widget build(BuildContext context) {
void toggleView() {
setState(() {
showlogin = !showlogin;
});
}
if (showlogin) {
return LoginPage(toggleView);
} else {
return SignUp(toggleView);
}
}
}
4️⃣create the following files in a single folder named Model with the different names. This folder will include the files which deal Model(data) part of the application.
- Constants.dart // you can add more value that you want to save in phone memory.
- SearchModel.dart(model data for user search list)
> user.dart
Step 1: Firebase Authentication in the App: Sign in, Sign up or Sing Out
This is a most essential part of any chat app to keep your data secure by directly sign-in the app with your username. So here’s what you need to understand to create a sign-in/Sign up with email and password.
If you are choosing to proceed with the Google Sign-in, then refer to this link for information: https://firebase.flutter.dev/docs/auth/usage
First Make the UI for the Login page.
As we know that we Will keep our all Authentication related function in a single dart file named authentication in the Services folder.
Include the following Functions in the dart file, We will use these functions at the time of implementation.
//code for google signUp using email and password
Future signUpWithEmailAndPassword(String email, String password) async {
try {
UserCredential userCredential = await _auth
.createUserWithEmailAndPassword(email: email, password: password);
User user = userCredential.user;
return _usercheck(user);
} on FirebaseAuthException catch (e) {
if (e.code == 'weak-password') {
print('The password provided is too weak.');
return 0;
}
else if (e.code == 'email-already-in-use') {
print('The account already exists for that email.');return 1;
}
} catch (e) {
print(e.toString());
}
}//Code for Google Signin using email and password
User1 _usercheck(User user) {
if (user != null) {
return User1(userId: user.uid);
} else {
return null;
}
}
Future signinWithEmailAndPassword(String email, String password) async {
try {
UserCredential userCredential = await _auth.signInWithEmailAndPassword(
email: email, password: password);
User user = userCredential.user;
return _usercheck(user);
} on FirebaseAuthException catch (e) {
if (e.code == 'user-not-found') {
print('No user found for that email.');
return 0;
} else if (e.code == 'wrong-password') {
print('Wrong password provided for that user.');
return 1;
}
}
}//Sign Out Function
Future signOut() async {
try {
BotToast.showText(
text: "logged out Successfully",
);
HelperFunction.saveuserLoggedInSharedPreference(false);
return await _auth.signOut();
} catch (e) {
print(e.toString());
}
}
}
Implementing the SignMeup function in Signup View file which we have to call under OnPressed method of a button by calling this function it will take the text from the text controller and call the required google signup function which we have added in authentication file.
Now as soon as users sign up for the first time we have to save the user info in phone memory we will do that using shared preferences and we have to make a user in the database to do that
add the following functions in database.dart file.
// We have to call this function as soon as user signup this function will upload the user data to Firestore for registration.
uploaduserInfo(userMap) {
FirebaseFirestore.instance.collection("users").add(userMap);
}
Step 2: Implementing Chat Home Screen
Now after logged in We have to create the Home screen which will contain the active Chats list.
Create a desired Ui for the home screen and use the below-provided code for backend integration.
Following function in the home.dart file will fetch the logged-in a username that we have saved during Sign in Process, then after fetching the logged-in username it will search the active chatroom in the firebase database which includes the name of the user.
The Above getuserInfo will fetch the following chatroom for database.chat room will be created when any one of two member message the other person for the first time. that we will implement later.
Now after Fetching the active chat room using the following chat list widget we will display each chat tile according to the data fetched.
Chat Tile
Step 3: Implementing Search Screen.
First, implement the search screen basic layout which will contain a text box for username to search. after pressing the search button the following code will be executed.
fetch function will call the getusername function. add the following function in database.dart file
This Function Will Search The user by its username in a database.
//getusername search function will fetch the username.//This function will append all searched user in List of type searchmodel
Now to show the fetched users list we will use the following list widget which will return the search tile which two-parameter that is a username and email id.
Now after clicking on each tile we want to the conversation screen where we can chat to the searched user. But First, we want to create the chat room in the database. for that call the following function which will create the chatroom with a specific unique id that id will be like username1_username2 .
it will create the chatroom in firestore database.
This function will create a unique id for the chatroom.
Step 4: Implementing Conversation Screen.
For the UI we need to include a text box and a button which will send the message and a chat list which will display the message from both users who are chatting with each other .. message from the receiver will display on the left and the message sent by the sender will appear on right.
Following is the chatmessagelist which will create a Stream of data to synchronize the message on the database and app
Now to send the message we need a function that will take the text from the text controller and call the set conversation method which we will include in the database.dart file.
Add the following method to the database.dart file. this method will send the message to the database.
Step 5: Implementing the Geo Location feature.
for this, we will add a button in the conversation screen app bar actions button pressing which we will be able to see the location of the user.
But first, we want every user should update its location to the database for this we want a function that will execute first on user's home screen or where ever you want. Add the following in database.dart and call them when you want the user to update its current location.
Now add the following to map.dart This will be the screen which will show your friends location on google map.
Thank You for Reading.