The tutorial app displays a list of friends contact details that are saved in the cloud using Firebase
Our tutorial app uses Firebase to save a number of friend’s names and telephone numbers in a Firebase Realtime Database.
The data is displayed in a list view. We also include a number of buttons which enable the user to:
- Load our dummy data
- Add details
- Replace details
- Update details
- Find details
- Delete details
The data is saved in the cloud and synced with all connected devices.
We also choose to persist the data on the device so that we can also access the data offline, to view, add, edit or delete names and telephone numbers. The data will be synced with the cloud database once the connection is resumed.
I don’t want to set the world on fire: So what’s a Firebase Realtime Database?
Yes, there’s a song with that title, why not check it out? by The Inkspots. However, it’s got nothing to do with the Firebase Realtime Database!
Firebase Realtime Databases:
- store and sync data with a NoSQL cloud database
- use JSON to store the data
The Firebase Realtime Database is hosted in the cloud. Your data is stored as JSON and synchronized in real time to all connected clients.
The Firebase Realtime Database lets you share your database across Android, IOS and Web apps.
Firebase data is also available offline, so your app always has access to your data. The data is automatically synced once the app comes back online.
- Realtime – means that data is synchronised with all connected devices within milliseconds of changes being made to the data
- Offline - the Firebase Realtime Database persists your data on your device so the data is always available, even offline. The data is synced with the cloud on reconnection
- Accessible from client devices - the Firebase Realtime Database can be accessed from a mobile device (Android or IOS) or Web app
- Security – you define your which controls who has what access to your Firebase database. You can also integrate Firebase to control access to your data
Little sparks: Enabling offline capabilities
You can enable disk persistence in your app so that when your app loses internet connection:
- Your users can access the cached data
- New user input is cached
- Cached data is synced with the cloud Firebase Realtime Database once the internet connection is re-established
Runaway fires: Saving other types of data
The Firebase Realtime Database is designed to only allow operations that will execute quickly.
I’m a Pyromaniac! I’ve got huge files!
You can use for more demanding operations to store files such as images, videos, and audio as well as other user-generated content.
Setting your app on fire: getting started with Firebase
Fuel, oxygen and heat is what you need
For your app to use Firebase, the minimum Android version required is 2.3 (Gingerbread).
It’s also recommended that you disable instant run if your version of Android Studio is less than version 2.2.
Lighting the fire: preparing your app for Firebase
It’s very easy to set up your app to use Firebase. The online documentation does a good job of explaining how to do that so we won’t repeat it here. Check out the .
Chopping the wood: the basic steps
Firstly, create your app in Android Studio and note its package name, you’ll need it in the next step, so copy it to the clipboard for pasting later.
Now, go to the and create a Google Project if you don’t have one. Then follow the instructions to add Firebase to your app. This involves entering your apps package name and downloading and installing a configuration file.
Next, add the Firebase SDK to your app by editing the build.gradle files.
Careful who you give your fire to: Configuring security rules
Firebase Authentication is required by default for your app to use your Firebase database.
To get started without having to set up Authentication, simply configure your Firebase database rules for public access. Note that this makes your database open to anyone, so be sure to restrict your database again when you set up authentication.
For more on how to configure the security rules, check out the documentation here
Fire Control: The Firebase Console
You can view and manage your Firebase Database in the .
Some of the things that you can do in your Firebase Console include:
- Adding, editing and deleting nodes
- Adding, editing and deleting child nodes
- Adding, editing and deleting values
Here’s what our tutorial app’s Firebase database looks like in the Firebase Console:
The Tree-like structure of the Firebase database can clearly be seen in this Firebase Console representation of our apps’ database
We use a custom Java class, Friend to represent each of our friend objects.
Coffee break! Java objects
The Firebase Realtime Database stores data as JSON. It therefore makes sense to save your data as Java objects which are then automatically mapped to child locations in the Firebase database.
Who needs friends: Our custom Friend Java object
We declare a Friend object in our tutorial app. Each Friend object consists of a:
- name
- telephone number
Don’t be a dummy: Our custom DummyData Java object
We also have a custom Java class, DummyData which we use to get a HashMap object containing seven dummy friend objects which we’ll load into our Firebase Realtime Database.
Building the fire: How does Firebase structure its data?
The Firebase Realtime Database stores your data as JSON objects. There are no tables or records, instead the data is represented as a node in the cloud based JSON tree. Each node has a unique key identifier which you can provide or let Firebase do it for you when you use the push() method.
Check this link out, http://www.json.org/, if you need more information on JSON.
For more on the Firebase data structure, ()
It’s easy to connect to your Firebase database once you’re done setting up your app.
Where there’s smoke, there’s fire: Here’s looking at our tutorial app
Let’s take a closer look at our tutorial apps’ code.
The onCreate() method
You only need a few lines of code to use your Firebase database. Here’s how we did it:
Three simple lines of code gets a reference to your database and ensures that it persists when the connection is lost
What’s happening here?
- Call setPersistenceEnabled(true) on your Firebase database instance so that your data is cached and available locally when the device loses internet connection. Do this before getting a reference to the database
- Get an instance of your Firebase database by calling getInstance()
- Get a reference to a child node within your Firebase database by calling getReference(), passing the path to the child node as a parameter. The Firebase reference represents a particular location in our database. We can then use it to read data from or write data to that location
Keeping it real: Updating your data in real time
You need to attach a listener to a database location if you want to update that particular set of data in real time. We do this by adding a ValueEventListener to our database reference, friendsDatabaseReference:
We attach a ValueEventListener to the Firebase database location that we want to monitor
Now, each time the data at that location changes, the listeners’ onDataChange() method will be triggered and the database updated. More on this later.
Writing data to the Firebase database
There are four methods that you can use to write data to your Firebase database:
- setValue() – writes or replaces data to a given location. We use this method in our tutorial app
- push() – adds to a list of data. A unique ID is generated when you call push() – we make use of this to get an ID when adding a friend using setValue() in our tutorial app
- updateChildren() – update some of the keys in the given location without replacing all of the data - see tutorial code for how it's done
- runTransaction() – updates complex data
We use the setValue() method in our tutorial app. It saves data to a specific location by replacing any data that is already there.
You can use setValue() to save different types of data to a Firebase database:
- String
- Long
- Double
- Boolean
- Map
- List
- Custom Java objects
It makes sense to use Java objects as:
- Your java objects’ contents are automatically mapped to child locations in the Firebase database
- Your code is easier to read and maintain
Adding fuel to the fire: Loading our dummy data
Pressing the Load Data button triggers the loadDummyDataHashMap() method which loads our dummy data into our Firebase Realtime Database.
Now you’re on fire! I think there’s another song in there by The Boss, maybe check it out.
Here’s the methods’ code:
Use the setValue() method to pass the HashMap of dummy data to our Firebase database
What’s happening here?
- We call setValue() on our database reference, friendsDatabaseReference passed as the friendsReference parameter here
- The reference represents the location in the database where we want to write the data to, in our case the friends node
- setValue() sets the data at this location to the data contained in the hash map (our dummy data)
- This triggers the ValueEventListener which is attached to the friends location and our list is updated. More on this later
Adding an item to the list
Pressing the Add Item button calls the appendFriendToExistingFriendsTree() method to add an item to the existing list.
Here’s the methods’ code:
Use the push() method and Firebase will give you a unique key
What’s happening here?
- We have a friend’s name and telephone number that we want to add to the list
- We also need a key to identify where in the Firebase database that we want to save this item. Calling push() on the database reference (which is the location, the friends node, of our data in the Firebase database) generates and returns a unique key that we can use
- We construct our new Friend object
- Finally, we call setValue() and pass our new Friend object to be saved in the database. The friendsReference database reference identifies the location in the Firebase database where we want to save this Friend object and the key identifies the position within that location
- Any listeners attached to the friendsReference (our database reference) will be triggered and the list updated
Loading a single item
Pressing the Replace Items button calls the loadSingleItem() method which uploads the given data to the Firebase Realtime Database, replacing any data currently at the given location.
Here’s the methods’ code:
Create a new hash map and pass it to the database to replace the existing data
What’s happening here?
- We have a friend’s name and telephone number that we want to save in the Firebase database. We specify where in the given location that we want to put this data by defining a key
- We create our new Friend object, setting the name and telephone number values
- We create a HashMap and put our Friend java object in the map as a value and the database key as the maps’ key
- Finally, we get a database reference which specifies the Firebase database location and then call setValue() passing the hash map as the parameter
- The data is written to the Firebase database at the friends location, replacing any data that may be there
- Any listeners attached to the database location will be triggered and the list updated
Updating an item
Pressing the Update Item button triggers the updateFriend() method which replaces an existing item in the Firebase Realtime Database with a new item. It does not affect the rest of the database.
Here’s the methods’ code:
Use the child’s key to identify the specific data
What’s happening here?
- We have our new friend’s name and telephone number. We also have a key which identifies which item in the Firebase database that we want to update
- Finally we set the values for the name and telephone number to our new values by using the database reference which locates our friends database, getting the specific child that we want to update by using the key as the identifier within the friends database. We then use the child identifiers, friendName and telephoneNumber to identify the specific values that we want to update at the given item which is identified by the key
- Any listeners attached to the database location will be triggered and the list updated
I still haven’t found what I’m looking for: Doing a query
by U2. Yes, that’s another song that has got nothing to do with this tutorial but you can give it a listen if you want.
Pressing the Find Item button triggers the FindItem() method which searches the Firebase Realtime Database for the given item. An appropriate Toast message is displayed if it’s found.
Here’s the methods’ code:
Use the equalTo() method in a Query to find a matching value
What’s happening here?
- We specify the child, friendName and its corresponding value Peter Pan, that we’re looking for
- Then we build our query:
- We use the database reference, friendsDatabaseReference to identify the location of the data that we’re looking for
- We want the data to be ordered by the child, friendName so we use the orderByChild() method
- We’re looking for the item in the database whose child, friendName value matches our value of Peter Pan so we use the equalTo() method
- Finally we attach a ChildEventListener listener to our query. This listener will be triggered when the item is found. More on this later
Delete an item
Pressing the Delete Item button, triggers the deleteItem() method which deletes the given item from the Firebase Realtime Database.
Here’s the methods’ code:
We first find the item that we’re looking for and then we delete it
What’s happening here?
- We build our query, using the database reference to identify the location of the data. We’re going to look at that location for an item identified by the child key, friendName. We use the equalTo() method to find a data item whose friendName value matches our search term, Vicky Victoria
- We then attach a single ValueEventListener listener to this query reference. This listener is triggered when the matching item is found. We can then delete the item
The Listener interfaces
We attach listeners to monitor locations. Events are then triggered when data at that location is read, written, changed or removed.
There are a number of listeners that you can use.
The ValueEventListener
Use the ValueEventListener to listen for any changes to data at a specific location.
Use addValueEventListener() to attach the listener to the location, for example, to a DatabaseReference object.
The ValueEventListener has two methods:
- onCancelled() – is triggered if the listener failed or was removed for security reasons
- onDataChange() – is triggered each time the data at the specified location has been read or changed. It returns a snapshot of the data at the specified location
Here’s part of the code for our ValueEventListener:
Use the addValueEventListener() method to monitor changes in data at a specific location
What’s happening here?
- Calling addValueEventListener() attaches this listener to the location represented by the Firebase database reference, friendsReference. Any changes to data at this location will trigger this listener
- The listener’s onDataChange() method is triggered whenever data at the monitored location changes. The method receives a snapshot of the data at that location which we can then access
- getChildren() returns the children of this snapshot as an Iterable object. This enables us to get an Iterator so that we can treat the snapshot as a collection
- using the iterator, we get our Friend object out of the snapshot and add it to the friendsList, a List of Friend objects
- we then set up the adapter and attach the adapter to the list view
- for more on Adapters, check out our tutorial, Android Adapters: What are Adapters?
- for more on Lists, check out our Android ListView tutorial
The result of using the ValueEventListener is that:
- the listener’s onDataChange() method is triggered each time data at the location represented by the database reference changes
- we can then update the list view to display the current data at that location
The ChildEventListener
Use the ChildEventListener to listen for any changes to data at a specific child location of a given database reference.
Use addChildEventListener() to attach the listener to the location, for example, to a DatabaseReference object.
The ChildEventListener has five methods, each (except for onCancelled()) returning a snapshot of the data at the specified location:
- onCancelled() - is triggered if the listener failed or was removed for security reasons
- onChildAdded() – is triggered when a new child is added to the specified location
- onChildChanged() – is triggered each time the data at the specified child location has been read or changed. It returns a snapshot of the data at the specified location
- onChildMoved() – is triggered when the child location’s priority changes. Priorities determine how the children are ordered
- onChildRemoved() – is triggered when a child is removed from the specified location
We’ve attached a ChildEventListener to our query where we want to find a Friend object with the friendName of Peter Pan.
Note that this listeners’ methods will not be triggered unless the listener is attached to the location. So, in our app, you first have to press the Find Item button to attach the listener.
Here’s the code for the query:
Add a listener to your query to listen for the query result
And here’s a bit of the code for our childEventListener:
Use the ChildEventListener to monitor changes in data at a child location
What’s happening here?
- onChildAdded() – this method is triggered when a new child (that matches the details in our query) is added to the child location or the data at that location is read (providing that it contains data that matches our query). We then get the data out of the returned DataSnapshot object and display an appropriate Toast message
- onChildChanged() – this method is triggered when the data at the specified location (providing that it matches our query) is changed. We then get the data out of the returned DataSnapshot object and display an appropriate Toast message. You can test this in the Firebase Console. Make changes to the Peter Pan item (but don’t alter the friendName Peter Pan value) and you’ll notice that the onChildChanged() method is triggered
The single ValueEventListener
We’ve attached a single ValueEventlistener to our deleteQuery object by calling the addListenerForSingleValueEvent() method.
The single ValueEventListener is triggered once when the match is found and returns the data at that location.
Here’s the important bit of this methods’ code:
The DataSnapshot contains a snapshot of the data at the specified location
What’s happening here?
- The onDataChange() method is triggered when the matching record is read (in our case the matching item is found). It receives a snapshot of the data at the specified location as a DataSnapshot object
- The DataSnapshot object is returned whenever you read Database data
- Calling getChildren() gives us an Iterable<> object that allows us access to the immediate children of the snapshot
- We call next() on the iterator to get the first object in the snapshot. Then we call getValue(), passing the Friend parameter so that we get a Friend object returned
- Finally we use an if statement to check whether the returned name matches our query name, Vicky Victoria. If it does then we get its key value and use it when we call removeValue() to delete the data identified by that key
I hope that you have found this tutorial useful, if you did, please consider to keep me awake!. Thanks.
You may also be interested in other forms of data storage, so why not check out these tutorials:
- Using a SQLite database in Android
- Using Android’s SharedPreferences to save persistent data: a practical example and tutorial
- Using Android’s file system for saving application data
- Realm databases for Android beginners
Go to our Downloads section to download the files for this tutorial project