In this code lab you'll build a chat application for Android using Firebase and Android Studio.
What you'll learn:
- Interacting with Firebase from an Android application
The steps:
- Register with Firebase
- Create a project in Android Studio
- Connect the Android app to Firebase
- Send a message
- Show the messages
- Enable login
What you'll need
- Android Studio version 1.3 or up
- A test device or emulator with Android 2.3.3 or up
- The device must have internet access to the Firebase servers
- While we'll show you what to do in Android Studio, this code lab does not explain how Android works
The first step is to create a Firebase application. This will be the server-side component that our Android application talks to.
- Go to the Firebase web site
- Login or sign up
- Manage the app that was automatically created for you
This app is on Firebase's free hacker plan. This plan is great for when you're developing your app on Firebase. 4. Any data that our Android application writes, will be visible in the Data tab
The custom Firebase backend for our application is now ready for use. Let's set up our app in Android Studio.
In this step we'll create a project in Android Studio.
- Start Android Studio and Start a new Android Studio project
- You can name the project anything you want. But in the code below, we've named it Nanochat
- Set the minimum SDK to 10 or higher.
We've left it on 10 (Gingerbread) here, since that is the lowest API level Firebase supports. 4. Start with a Blank Activity
- We'll leave all the defaults for this activity
- If the project outline is not visible on the left, click the 1:Project label
- Open up the main activity, which can be found in
app/res/layout/activity_main.xmland switch from its Design to its Text tab if needed. In this file the root element will be aRelativeLayoutand in there will be aTextView. We won't be using theTextView, so delete it (or leave it and put a welcome message in it).
We now have a blank project in Android Studio. Let's wire our app up to Firebase!
Before we can start writing code that interacts with our Firebase database, we'll need to make Android Studio aware that we'll be using Firebase. We need to do this in a few places: in the gradle.build script for our app and in its AndroidManifest.xml.
-
open Gradle Scripts > build.gradle (Module: app)
This file contains the steps that Android Studio uses to build our app. We'll add a reference to Firebase to it, so we can start using it.
-
add the following lines to the dependencies object at the bottom:
compile 'com.firebase:firebase-client-android:2.3.1' compile 'com.firebaseui:firebase-ui:0.2.0'
This tells Gradle to include the Firebase SDK and the FirebaseUI library.
-
Add the following inside the
androidobject:packagingOptions { exclude 'META-INF/LICENSE' exclude 'META-INF/LICENSE-FIREBASE.txt' exclude 'META-INF/NOTICE' }
This tells Gradle to exclude some files that otherwise create conflicts during the build.
-
At this stage you'll need to synchronize the project with the gradle files again. Either click the Sync Now link in the notification bar or the corresponding button in the toolbar: Sync Project with Gradle Files.
Android Studio will parse the gradle files and pick up our changes.
-
Since Firebase is a hosted service, our app will need to be able to access the internet.
-
Open app > manifests > AndroidManifest.xml
-
Add this line inside the
manifestelement:<uses-permission android:name="android.permission.INTERNET" /> -
Now we can get to the Java code. The first step there is to set up initial connection between our code and its Firebase backend. open
MainActivity.javaand add this code to the end of theonCreatemethod:Firebase.setAndroidContext(this);
This code allows the Firebase client to keep its context. 9. Import Firebase at the top of your MainActivity by adding the following line:
import com.firebase.client.Firebase;
-
If Android Studio is having trouble finding the Firebase class, be sure that you've added dependencies and have synchronized the build file with the project.
-
We also want to create a connection to our database. We'll keep this connection in a member field:
private Firebase mFirebaseRef;
that we initialize in onCreate:
mFirebaseRef = new Firebase("https://<your-app>.firebaseio.com");
Be sure to replace <your-app> with the name of the Firebase app you created in the first section.

That's all the setup that is required. Next up we'll allow the user to enter a message in our app and send the message to Firebase.
Next we'll send data to Firebase! In this step we'll allow the user to enter a message in a text box. When they then click the Send button, we will send the message to Firebase.
-
We'll first add the necessary views to activity_main.xml:
<LinearLayout android:id="@+id/footer" android:layout_alignParentBottom="true" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <EditText android:id="@+id/text_edit" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:singleLine="true" android:inputType="textShortMessage" /> <Button android:id="@+id/send_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Send" /> </LinearLayout>
This layout puts a horizontal bar at the bottom that contains an EditText, where the user can enter their chat message, and a Button that they can click to send the message.
-
In our
MainActivity.javawe'll now add variables for theEditTextandButtonat the end of the onCreate method:final EditText textEdit = (EditText) this.findViewById(R.id.text_edit); Button sendButton = (Button) this.findViewById(R.id.send_button);
-
Next, we'll add a method that grabs the text from the input and send it to our Firebase database:
sendButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String text = textEdit.getText().toString(); Map<String,Object> values = new HashMap<>(); values.put("name", "Android User"); values.put("text", text); mFirebaseRef.push().setValue(values); textEdit.setText(""); } });
You will have to import the packages for some of these classes. Android Studio will tell you where to import them from.
Here we grab the message from the EditText, add it to a Map, and send it off to Firebase. We'll look at a way to replace that Map with something more type-safe in the next section, but for now this will work.
We hard-coded our user name for the moment. We'll use Firebase Authentication to make this dynamic in the last section of this code lab.
- If you now run the application in the emulator, you will see an input field with a Send button that sends the message to Firebase. Open the URL of your Firebase database, and you'll see it light up green as you add new messages.
- Open the Data tab in the Firebase Dashboard of your app. You'll see it light up green as you add new messages. Admit it, this is pretty cool!
Now that we can send messages to Firebase, it is time for the next step: making the messages show up in our Android app in realtime.
A chat app that doesn’t show existing messages is not very useful. So in this step we’ll add a list of the existing messages to our Android app. And since we're using Firebase, new chat messages will be added to this list automatically. At the end of this section we’ll have a fully functional chat app.
Let's take this in chunks: first we'll create a Java class to represent each message, then we'll create an Adapter that gets each of the messages from Firebase and puts them into a ListView.
-
As you can see in the screenshot, each chat message has the same layout. Instead of creating a custom layout, we'll use one of the built-in layouts of Android:
android.R.layout.two_line_list_item. We'll show the user name on the first line (in bold) and the message text on the second line. -
Create a class
ChatMessage.javathat wraps the username and text message:public class ChatMessage { private String name; private String text; public ChatMessage() { // necessary for Firebase's deserializer } public ChatMessage(String name, String text) { this.name = name; this.text = text; } public String getName() { return name; } public String getText() { return text; } }
As you can see, this is plain-old Java object. But it’s a POJO with some special traits. First ChatMessage follows a JavaBean pattern for its property names. The getName method is a getter for a name property, while getText() is a getter for a text property. And second, those property names correspond to the ones we’ve been using when we sent messages to Firebase in our OnClickListener.
Warning: if you end up making this ChatMessage an inner class of another class, you must make it static: public static class ChatMessage.
- With the layout for the message specified and their structure defined in a class, we need to make a space for them in the
main_activity.xml
Add a ListView with `android:id="@android:id/list"`` above the LinearLayout:
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/footer"/>
This is the container that all messages will be added to: one message_layout for each ChatMessage.
The id value is very important here, since Android's ListActivity uses it to find the ListView. So make sure to enter it exactly as specified: ``@android:id/list`.
-
Make the
MainActivityclass descend fromListActivity. This is a built-in Android base-class. By deriving from this, our activity will automatically have access to the ListView we added to the layout:public class MainActivity extends ListActivity { -
We're ready to start on our ListAdapter, which we'll base on the
FirebaseListAdapterfrom the firebase-ui project we imported.The FirebaseListAdapterclass adapts a Firebase collection so that it becomes usable in an AndroidListView. First we'll add a member to ourMainActivity:public class MainActivity extends ListActivity { private Firebase mFirebaseRef; FirebaseListAdapter<ChatMessage> mListAdapter;
-
To make everything come together, we add this to the onCreate method of our MainActivity:
mListAdapter = new FirebaseListAdapter<ChatMessage>(this, ChatMessage.class, android.R.layout.two_line_list_item, mFirebaseRef) { @Override protected void populateView(View v, ChatMessage model) { ((TextView)v.findViewById(android.R.id.text1)).setText(model.getName()); ((TextView)v.findViewById(android.R.id.text2)).setText(model.getText()); } }; setListAdapter(mListAdapter);
The FirebaseListAdapter maps the data from your Firebase database into the ListView that you added to the layout. It creates a new instance of your two_line_list_item for each ChatMessage and calls the populateView method. We override this method and put the name and text in the correct subviews.
-
Don't worry, the hardest part is behind us now. All that is left in this step is some clean-up. But before that, run your app and see that it shows all existing messages. And if you send a new message, it shows up in the emulator and in your Firebase dashboard.
-
The cleanup is minor, but it's important to keep our code as readable as possible at all times. Remember that onSendButtonClick method that we wrote in step 5? That use of a Map looked a bit messy. Now that we have a ChatMessage class, we can make it much more readable:
sendButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String text = textEdit.getText().toString(); ChatMessage message = new ChatMessage("Android User", text); mFirebaseRef.push().setValue(message); textEdit.setText(""); } }); -
Finally, we also need to clean up our list adapter when the activity is destroyed. This will close the connection to the Firebase server, when the activity is not showing.
@Override protected void onDestroy() { super.onDestroy(); mListAdapter.cleanup(); }
In this section we made our app show the chat messages. It was a lot of work, but in the end you can see that the Java code for our main activity still fits in a single screenshot.
As a final step, we're going to allow the users of our app to log in using email and password.
- In the Login & Auth tab of your Firebase dashboard, enable Email & Password authentication
-
First add a button to the top right of activity_main.xml
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Login" android:id="@+id/login" android:layout_alignTop="@android:id/list" android:layout_alignRight="@android:id/list" android:layout_alignEnd="@android:id/list" />
- Now create a new layout called dialog_signin.xml
-
In this dialog_signin.xml, we'll model the body of the sign-in dialog
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content"> <EditText android:id="@+id/email" android:inputType="textEmailAddress" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:layout_marginLeft="4dp" android:layout_marginRight="4dp" android:layout_marginBottom="4dp" android:hint="Email" /> <EditText android:id="@+id/password" android:inputType="textPassword" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:layout_marginLeft="4dp" android:layout_marginRight="4dp" android:layout_marginBottom="16dp" android:hint="Password"/> </LinearLayout>
We have two EditText controls under each other, one for the user's name, the other for their password.
The rest of the popup will be handled by a stock Android dialog.
-
Since our app will display the sign-in dialog as a popup, add the handling to MainActivity.java:
Button loginButton = (Button) findViewById(R.id.login); loginButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new AlertDialog.Builder(MainActivity.this) .setMessage("Enter your email address and password") .setTitle("Log in") .setView(MainActivity.this.getLayoutInflater().inflate(R.layout.dialog_signin, null)) .setNegativeButton("Cancel", null) .setPositiveButton("OK", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { AlertDialog dlg = (AlertDialog) dialog; final String email = ((TextView)dlg.findViewById(R.id.email)).getText().toString(); final String password =((TextView)dlg.findViewById(R.id.password)).getText().toString(); // TODO: sign in to Firebase } }) .create() .show(); } });
This method builds and show the dialog, with our two text boxes as the main body.
When the user clicks OK, it extracts the email address and password from the text controls.
-
Now wire the values that we got from the dialog to the Firebase Authentication back-end. Replace the
TODOwith the following code:mFirebaseRef.createUser(email, password, new Firebase.ResultHandler() { @Override public void onSuccess() { mFirebaseRef.authWithPassword(email, password, null); } @Override public void onError(FirebaseError firebaseError) { mFirebaseRef.authWithPassword(email, password, null); } });
In this code, we always try to register the user. If the user already registered that will result in onError, otherwise it will result on onSuccess.
Either way, we next call authWithPassword to authenticate the (pre-existing or just-created) user.
- With the above we have the registration/login flow working. But we still need to listen to when Firebase Authentication tells us the user has been authenticated, so that we can store the username and use that in the chat message instead of the hard-coded value we have now.
Add a field to the class to hold the user name:
String mUsername;
Add the end of the onCreate method, add a callback method that listens for authentication state changes in Firebase:
mFirebaseRef.addAuthStateListener(new Firebase.AuthStateListener() {
@Override
public void onAuthStateChanged(AuthData authData) {
if(authData != null) {
mUsername = ((String)authData.getProviderData().get("email"));
findViewById(R.id.login).setVisibility(View.INVISIBLE);
}
else {
mUsername = null;
findViewById(R.id.login).setVisibility(View.VISIBLE);
}
}
});
Firebase calls our listener whenever the authentication state changes, so whenever the user logs in or out. When the user logs in, we store their email address in our field and hide the login button.
Firebase Authentication supports multiple authentication providers and each of them exposes a different set of data. For example, if we'd allow our users to authenticate with their existing Twitter account, we could identify them by their twitter handle.
-
Finally, replace the hard-coded username with the field we just populated:
mFirebaseRef.push().setValue(new ChatMessage(MainActivity.this.mUsername, message));
We could definitely improve the layout of things. But this step has been long enough as it is. So let's wrap up with a few notes.
-
One thing you may note is that the user stays logged in, even when they restart the app. If instead you want to sign out the user, you can call:
mFirebaseRef.unauth();
This will trigger the AuthStateListener we created before, which will clear the username field and re-enable the login button.
- If you want to know which users logged in to your application, you can find them in the Login & Auth tab of your Firebase's dashboard.
This is also where you can configure the password reset emails that you can send to your users, in case they forgot their password.
Wrap-up
Congratulations! You've just built a fully functional multi-user chat application that uses Firebase to store the data and authentication users.
As a reward for finishing the codelab you’ve earned a promo code! When you’re ready to put your Firebase app in production, you can use the promo code androidcodelab49 for $49 off your first month of a paid Firebase plan. Just enter the code when you upgrade your Firebase.
What we've covered
- Interacting with a Firebase Database from an Android application.
- Using Firebase Authentication in an Android application to authenticate users.
Next Steps
- Add a log-out button to the app
- Add a password-reset button to the login dialog
- Use a RecyclerView (and
FirebaseRecyclerViewAdapter) to ensure the activity also performs well when there are lots of messages - Allow the user to specify a nickname or use one of the Firebase's social authentication providers to look up their first name.
- Get your app on the Play Store!
Learn More
- Learn all about using Firebase with Android by following the Firebase for Android development guide.
- Study a more advanced sample application: AndroidDrawing.
- Learn about GeoFire for Java, which allows you to add realtime location queries to your Android application



































