You're viewing the legacy docs. They are deprecated as of May 18, 2016.
These docs are for version 2.5.2 and below of the Java SDK. Go to our current docs, or see our Android migration guide.

Java Android Guide

Understanding Data

It's a JSON Tree

All Firebase database data is stored as JSON objects. There are no tables or records. When we add data to the JSON tree, it becomes a key in the existing JSON structure. For example, if we added a child named widgets under users/mchen/, our data looks as follows:

  "users": {
    "mchen": {
      "friends": { "brinchen": true },
      "name": "Mary Chen",
      // our child node appears in the existing JSON tree
      "widgets": { "one": true, "three": true }
    "brinchen": { ... },
    "hmadi": { ... }

In Java this JSON tree is translated into one of several types of objects:

  • String
  • Boolean
  • Long
  • Double
  • Map<String, Object>
  • List<Object>

This list is recursive; the possible types for Object in the above list is given by the same list (that is, Object can be a Boolean, Long, Double, Map, or List). These types correspond to the types available in JSON.

Creating a Firebase database Reference

To read and write database data, we first create a reference to the Firebase database. This data to be loaded is specified with a URL.

Firebase rootRef = new Firebase("");

Creating a reference does not create a connection to the server or begin downloading data. Data is not fetched until a read or write operation is invoked. Once it is retrieved, it stays cached locally until the last event listener is removed.

Firebase provides an application which displays a visual representation of the database data and provides tools for simple administrative tasks. We refer to this as the app dashboard. All the data in this guide is stored in the docs-examples Firebase database; a read-only version of the app dashboard can be viewed by going to the Firebase URL in a browser.

It's possible to directly access child nodes in the data as well. For example, to point to Mary Chen's name, simply append users/mchen/name to the URL:

Firebase rootRef = new Firebase("");

We can achieve the same result from an existing parent reference by using the child() API call:

Firebase rootRef = new Firebase("");

In a similar fashion, it's possible to drill down directly to the database data in the application Dashboard by simply adding the child path to the URL.

Lists and Arrays in a Firebase database

Firebase databases have no native support for lists or arrays. If we try to store an list or an array, it really gets stored as an "object" with integers as the key names.

// we send this
['hello', 'world']
// Firebase databases store this
{0: 'hello', 1: 'world'}

However, to help developers that are storing arrays in a Firebase database, when data is read using getValue() or via the REST api, if the data looks like an array, Firebase clients will render it as an ArrayList. In particular, if all of the keys are integers, and more than half of the keys between 0 and the maximum key in the object have non-empty values, then Firebase clients will render it as an ArrayList. This latter part is important to keep in mind.

// we send this
['a', 'b', 'c', 'd', 'e']
// Firebase databases store this
{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e'}

// since the keys are numeric and sequential,
// if we query the data, we get this
['a', 'b', 'c', 'd', 'e']

// however, if we then delete a, b, and d,
// they are no longer mostly sequential, so
// we do not get back an array
{2: 'c', 4: 'e'}

It's not currently possible to change or prevent this behavior. Hopefully understanding it will make it easier to see what one can and can't do when storing array-like data.

Why not just provide full array support? Since array indices are not permanent or unique, concurrent real-time editing will always be problematic.

Consider, for example, if three users simultaneously updated an array on a remote service. If user A attempts to change the value at key 2, user B attempts to move it, and user C attempts to change it, the results could be disastrous. For example, among many other ways this could fail, here's one:

// starting data
['a', 'b', 'c', 'd', 'e']

// record at key 2 moved to position 5 by user A
// record at key 2 is removed by user B
// record at key 2 is updated by user C to foo

// what ideally should have happened
['a', 'b', 'd', 'e']

// what actually happened
['a', 'c', 'foo', 'b']

So when is it okay to use an array? If all of the following are true, it's okay to store the array in your Firebase database:

  • Only one client is capable of writing to the data at a time
  • To remove keys, we save the entire array instead of using removeValue()
  • We take extra care when referring to anything by array index (a mutable key)
Read more about arrays in our blog post: Best Practices: Arrays in Firebase.

Limitations and Restrictions

A quick reference to limitations in data storage and read ops in a Firebase database.

Description Limit Notes
Depth of child nodes 32
Length of a key 768 bytes UTF-8 encoded, cannot contain . $ # [ ] / or ASCII control characters 0-31 or 127
Size of one child value 10mb UTF-8 encoded
Write from SDK 16mb UTF-8 encoded
Write from REST 256mb
Nodes in a read operation 100 million

Backups and Restores

Firebase performs automated backups of all Firebase databases daily. The backups are stored for 60 days at an off-site facility. Since these backups are done at the hardware level, they do not affect your bandwidth usage or performance. These backups are primarily for disaster recovery, but can be made available to developers on a case-by-case basis for purposes of emergency restores.

Firebase also offers optional, private backups to a Google Cloud Storage (GCS) bucket or an Amazon Simple Storage Solution (S3) bucket, for databases which have upgraded to the Bonfire, Blaze, or Inferno plan. Since these backups are done at the hardware level, they do not count against your bandwidth usage and do not affect performance of the database. Email to enable this feature for your database.

It is also possible to create manual backups via the REST API. For databases with less than 200MB of data, this can be done by simply requesting the entire database using the root URL. For larger instances, you should break up your data by path or by key and retrieve it in smaller chunks.

Keep in mind that backing up data via the REST API does count against your bandwidth usage, and it can affect performance. Backups of large data (gigabytes) should be spread over a large time frame to reduce the impact on clients connected to the database.

For more information about chunking data and creating backups of big data, see the REST API's query parameters. Used together, startAt, limitToFirst, and shallow=true arguments can be used to index keys for any amount of data, and retrieve it in manageable segments.

  1. 1


    Installation & Setup

  2. 2


    Understanding Data

  3. 3


    Saving Data

  4. 4


    Retrieving Data

  5. 5


    Structuring Data

  6. 6


    Understanding Security

  7. 7


    User Authentication

  8. 8


    Offline Capabilities