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.
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.
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.
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
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.