In this tutorial you will learn to build an android real time chat application using firebase database.
Before reading this tutorial I hope you are already familiar with basic read and write operations on firebase. If you don’t know then I would recommend you to follow below link to get basic overview about firebase.
Read: https://firebase.google.com/docs/database/android/start/
I have developed a very basic and simple chat app in which user can login and register in the system and can do one to one chat with other users.
![Android Real Time Chat Application Using Firebase Tutorial 1]()
Video Demo
Watch below video to see how the app works.
Android Real Time Chat Application Using Firebase Tutorial
Firebase
Go to firebase console and create a new project.
Link: https://console.firebase.google.com/
Select Database option in left sidebar. The database structure used in this project looks as shown in below image.
![Android Real Time Chat Application Using Firebase Tutorial 2]()
In my case the database base url is https://android-chat-app-e711d.firebaseio.com/. It will be different in your case so make sure to change the url wherever used in the code.
Android Studio
Create a new android studio project with package name com.androidchatapp
Now add dependency for firebase database and volley in build.gradle (Module: app) file. Add following lines under dependency section and sync the project.
compile 'com.firebase:firebase-client-android:2.5.2+'
compile 'com.android.volley:volley:1.0.0'
Add internet access permission in AndroidManifest.xml file.
<uses-permission android:name="android.permission.INTERNET" />
The android studio project has following structure.
![Android Real Time Chat Application Using Firebase Tutorial 3]()
Add following code in respective files.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.androidchatapp">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".Login">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".Register" />
<activity android:name=".Users" />
<activity android:name=".Chat" />
</application>
</manifest>
rounded_corner1.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#dddddd" />
<stroke
android:width="0dip"
android:color="#dddddd" />
<corners android:radius="10dip" />
<padding
android:bottom="5dip"
android:left="5dip"
android:right="5dip"
android:top="5dip" />
</shape>
rounded_corner2.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#f0f0f0" />
<stroke
android:width="0dip"
android:color="#f0f0f0" />
<corners android:radius="10dip" />
<padding
android:bottom="5dip"
android:left="5dip"
android:right="5dip"
android:top="5dip" />
</shape>
activity_chat.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.androidchatapp.Chat">
<ScrollView
android:layout_width="match_parent"
android:layout_weight="20"
android:layout_height="wrap_content"
android:id="@+id/scrollView">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="@+id/layout1">
</LinearLayout>
</ScrollView>
<include
layout="@layout/message_area"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom"
android:layout_marginTop="5dp"/>
</LinearLayout>
activity_login.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.androidchatapp.Login"
android:orientation="vertical"
android:gravity="center">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Login"
android:textSize="30dp"
android:gravity="center"
android:layout_marginBottom="20dp"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/username"
android:inputType="text"
android:maxLines="1"
android:hint="enter username"
android:layout_marginBottom="10dp"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/password"
android:inputType="textPassword"
android:maxLines="1"
android:hint="enter password"
android:layout_marginBottom="10dp"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Login"
android:id="@+id/loginButton"
android:layout_marginBottom="20dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Click here to register"
android:textSize="20dp"
android:gravity="center"
android:id="@+id/register"/>
</LinearLayout>
activity_register.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.androidchatapp.Register"
android:orientation="vertical"
android:gravity="center">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Register"
android:textSize="30dp"
android:gravity="center"
android:layout_marginBottom="20dp"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/username"
android:inputType="text"
android:maxLines="1"
android:hint="enter username"
android:layout_marginBottom="10dp"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/password"
android:inputType="textPassword"
android:maxLines="1"
android:hint="enter password"
android:layout_marginBottom="10dp"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Register"
android:id="@+id/registerButton"
android:layout_marginBottom="20dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Click here to login"
android:textSize="20dp"
android:gravity="center"
android:id="@+id/login"/>
</LinearLayout>
activity_users.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.androidchatapp.Users"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="No users found!"
android:id="@+id/noUsersText"
android:visibility="gone"/>
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/usersList"/>
</LinearLayout>
message_area.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimaryDark"
android:gravity="bottom"
android:orientation="horizontal">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColorHint="#CFD8DC"
android:textColor="#CFD8DC"
android:hint="Write a message..."
android:id="@+id/messageArea"
android:maxHeight="80dp"
/>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="4"
android:padding="4dp"
android:src="@android:drawable/ic_menu_send"
android:id="@+id/sendButton"/>
</LinearLayout>
Chat.java
package com.androidchatapp;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import com.firebase.client.ChildEventListener;
import com.firebase.client.DataSnapshot;
import com.firebase.client.Firebase;
import com.firebase.client.FirebaseError;
import java.util.HashMap;
import java.util.Map;
public class Chat extends AppCompatActivity {
LinearLayout layout;
ImageView sendButton;
EditText messageArea;
ScrollView scrollView;
Firebase reference1, reference2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
layout = (LinearLayout)findViewById(R.id.layout1);
sendButton = (ImageView)findViewById(R.id.sendButton);
messageArea = (EditText)findViewById(R.id.messageArea);
scrollView = (ScrollView)findViewById(R.id.scrollView);
Firebase.setAndroidContext(this);
reference1 = new Firebase("https://android-chat-app-e711d.firebaseio.com/messages/" + UserDetails.username + "_" + UserDetails.chatWith);
reference2 = new Firebase("https://android-chat-app-e711d.firebaseio.com/messages/" + UserDetails.chatWith + "_" + UserDetails.username);
sendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String messageText = messageArea.getText().toString();
if(!messageText.equals("")){
Map<String, String> map = new HashMap<String, String>();
map.put("message", messageText);
map.put("user", UserDetails.username);
reference1.push().setValue(map);
reference2.push().setValue(map);
}
}
});
reference1.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Map map = dataSnapshot.getValue(Map.class);
String message = map.get("message").toString();
String userName = map.get("user").toString();
if(userName.equals(UserDetails.username)){
addMessageBox("You:-\n" + message, 1);
}
else{
addMessageBox(UserDetails.chatWith + ":-\n" + message, 2);
}
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(FirebaseError firebaseError) {
}
});
}
public void addMessageBox(String message, int type){
TextView textView = new TextView(Chat.this);
textView.setText(message);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
lp.setMargins(0, 0, 0, 10);
textView.setLayoutParams(lp);
if(type == 1) {
textView.setBackgroundResource(R.drawable.rounded_corner1);
}
else{
textView.setBackgroundResource(R.drawable.rounded_corner2);
}
layout.addView(textView);
scrollView.fullScroll(View.FOCUS_DOWN);
}
}
Login.java
package com.androidchatapp;
import android.app.ProgressDialog;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONException;
import org.json.JSONObject;
public class Login extends AppCompatActivity {
TextView register;
EditText username, password;
Button loginButton;
String user, pass;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
register = (TextView)findViewById(R.id.register);
username = (EditText)findViewById(R.id.username);
password = (EditText)findViewById(R.id.password);
loginButton = (Button)findViewById(R.id.loginButton);
register.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(Login.this, Register.class));
}
});
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
user = username.getText().toString();
pass = password.getText().toString();
if(user.equals("")){
username.setError("can't be blank");
}
else if(pass.equals("")){
password.setError("can't be blank");
}
else{
String url = "https://android-chat-app-e711d.firebaseio.com/users.json";
final ProgressDialog pd = new ProgressDialog(Login.this);
pd.setMessage("Loading...");
pd.show();
StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>(){
@Override
public void onResponse(String s) {
if(s.equals("null")){
Toast.makeText(Login.this, "user not found", Toast.LENGTH_LONG).show();
}
else{
try {
JSONObject obj = new JSONObject(s);
if(!obj.has(user)){
Toast.makeText(Login.this, "user not found", Toast.LENGTH_LONG).show();
}
else if(obj.getJSONObject(user).getString("password").equals(pass)){
UserDetails.username = user;
UserDetails.password = pass;
startActivity(new Intent(Login.this, Users.class));
}
else {
Toast.makeText(Login.this, "incorrect password", Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
pd.dismiss();
}
},new Response.ErrorListener(){
@Override
public void onErrorResponse(VolleyError volleyError) {
System.out.println("" + volleyError);
pd.dismiss();
}
});
RequestQueue rQueue = Volley.newRequestQueue(Login.this);
rQueue.add(request);
}
}
});
}
}
Register.java
package com.androidchatapp;
import android.app.ProgressDialog;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.firebase.client.Firebase;
import org.json.JSONException;
import org.json.JSONObject;
public class Register extends AppCompatActivity {
EditText username, password;
Button registerButton;
String user, pass;
TextView login;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
username = (EditText)findViewById(R.id.username);
password = (EditText)findViewById(R.id.password);
registerButton = (Button)findViewById(R.id.registerButton);
login = (TextView)findViewById(R.id.login);
Firebase.setAndroidContext(this);
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(Register.this, Login.class));
}
});
registerButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
user = username.getText().toString();
pass = password.getText().toString();
if(user.equals("")){
username.setError("can't be blank");
}
else if(pass.equals("")){
password.setError("can't be blank");
}
else if(!user.matches("[A-Za-z0-9]+")){
username.setError("only alphabet or number allowed");
}
else if(user.length()<5){
username.setError("at least 5 characters long");
}
else if(pass.length()<5){
password.setError("at least 5 characters long");
}
else {
final ProgressDialog pd = new ProgressDialog(Register.this);
pd.setMessage("Loading...");
pd.show();
String url = "https://android-chat-app-e711d.firebaseio.com/users.json";
StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>(){
@Override
public void onResponse(String s) {
Firebase reference = new Firebase("https://android-chat-app-e711d.firebaseio.com/users");
if(s.equals("null")) {
reference.child(user).child("password").setValue(pass);
Toast.makeText(Register.this, "registration successful", Toast.LENGTH_LONG).show();
}
else {
try {
JSONObject obj = new JSONObject(s);
if (!obj.has(user)) {
reference.child(user).child("password").setValue(pass);
Toast.makeText(Register.this, "registration successful", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(Register.this, "username already exists", Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
pd.dismiss();
}
},new Response.ErrorListener(){
@Override
public void onErrorResponse(VolleyError volleyError) {
System.out.println("" + volleyError );
pd.dismiss();
}
});
RequestQueue rQueue = Volley.newRequestQueue(Register.this);
rQueue.add(request);
}
}
});
}
}
UserDetails.java
package com.androidchatapp;
public class UserDetails {
static String username = "";
static String password = "";
static String chatWith = "";
}
Users.java
package com.androidchatapp;
import android.app.ProgressDialog;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Iterator;
public class Users extends AppCompatActivity {
ListView usersList;
TextView noUsersText;
ArrayList<String> al = new ArrayList<>();
int totalUsers = 0;
ProgressDialog pd;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_users);
usersList = (ListView)findViewById(R.id.usersList);
noUsersText = (TextView)findViewById(R.id.noUsersText);
pd = new ProgressDialog(Users.this);
pd.setMessage("Loading...");
pd.show();
String url = "https://android-chat-app-e711d.firebaseio.com/users.json";
StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>(){
@Override
public void onResponse(String s) {
doOnSuccess(s);
}
},new Response.ErrorListener(){
@Override
public void onErrorResponse(VolleyError volleyError) {
System.out.println("" + volleyError);
}
});
RequestQueue rQueue = Volley.newRequestQueue(Users.this);
rQueue.add(request);
usersList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
UserDetails.chatWith = al.get(position);
startActivity(new Intent(Users.this, Chat.class));
}
});
}
public void doOnSuccess(String s){
try {
JSONObject obj = new JSONObject(s);
Iterator i = obj.keys();
String key = "";
while(i.hasNext()){
key = i.next().toString();
if(!key.equals(UserDetails.username)) {
al.add(key);
}
totalUsers++;
}
} catch (JSONException e) {
e.printStackTrace();
}
if(totalUsers <=1){
noUsersText.setVisibility(View.VISIBLE);
usersList.setVisibility(View.GONE);
}
else{
noUsersText.setVisibility(View.GONE);
usersList.setVisibility(View.VISIBLE);
usersList.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, al));
}
pd.dismiss();
}
}
Screenshots
![Android Real Time Chat Application Using Firebase Tutorial 5]()
![Android Real Time Chat Application Using Firebase Tutorial 7]()
You can download the apk and source code from below link.
Apk: http://www.mediafire.com/file/jwurkc69pag2u6w/Android+Chat+App_V1.0.apk
Source Code: http://www.mediafire.com/file/djl5s58sbw5kpma/AndroidChatApp.rar
Feel free to ask your queries by commenting below.
The post Android Real Time Chat Application Using Firebase Tutorial appeared first on The Crazy Programmer.