What You Need To Know About Firebase. 9 Useful Tips

27 Mar 2017
What You Need To Know About Firebase. 9 Useful Tips

Firebase is a cloud service that contains a number of functionalities such as: Authentication, Real Time Database, Storage, Notification and others. In this article we will focus mainly on RealTime Database and a little bit on Authentication. The main purpose of this article is to collect all of the required information about usage of Realtime database, because it is always better to have everything in one place. I populated all the useful info in 9 tips so here they are:

Tip 1

When creating a database model for the app, try to use less nested objects as possible. For example:

Show code

{
  // This is a poorly nested data architecture, because iterating the children
  // of the "chats" node to get a list of conversation titles requires
  // potentially downloading hundreds of megabytes of messages
  "chats": {
    "one": {
      "title": "Historical Tech Pioneers",
      "messages": {
        "m1": { "sender": "ghopper", "message": "Relay malfunction found. Cause: moth." },
        "m2": { ... },
        // a very long list of messages
      }
    },
    "two": { ... }
  }
}

If you will only need a title, the other nested data will also be fetched. This in turn may increase the fetching time.

Tip 2

Duplication of some fields is ok for Firebase in case when one objects has the properties of other. However, it’s better to duplicate some field rather than creating connections between two objects, hence make one request instead of two.

Tip 3

Communication between the Firebase database and the client is done by attaching listeners to DB nodes. Note that when you attach a listener to some node, it will trigger right away. So you should ignore the first offset trigger in case you want just to listen the node updates.

Tip 4

If it is necessary to read the list of objects from the node, you should iterate through snapshot’s children and read objects one by one. For example:

Show code

public void onDataChange(DataSnapshot dataSnapshot) {
        	List deliveries = new ArrayList<>();

        	for(DataSnapshot snapshot : dataSnapshot.getChildren()){
            	Foo foo = snapshot .getValue(Foo.class);
            	deliveries.add(foo);
        	}
    }

Tip 5

When reading an object and creating a Java class, you should follow specific conditions (where the object’s fields will be mapped):

  • There should be an empty constructor in Java class
  • Field names of Java class should be equal to field names of the object
  • For every Java class field there should be a getter method

If these conditions are not followed, the data will not be parsed.

Tip 6

When using authentication, it is necessary to check if the user exists and if the entered credentials are valid. In that case you can use exceptions. For example:

Show code

public void onComplete(@NonNull Task task) {

    if ( !task.isSuccessful() ) {
   	
   	 try {
   		 throw task.getException();
   	 } catch(FirebaseAuthInvalidUserException e) {
   		// No such user
   	 } catch(FirebaseAuthInvalidCredentialsException e) {
   		 //Credentials are invalid
   	 } catch(Exception e) {
   		 e.printStackTrace();
   	 }
   	 return;
    }
}

Tip 7

Firebase has poor filtering capabilities. For example you can make query based on only one condition, but you can not make a query like “WHERE … AND … AND ...”. In this situation it is necessary to create one extra field in the object, that will contain the values, and by using them the filtering should be. For example:

Show code

"movie1": {
    "genre": "comedy",
    "name": "As good as it gets",
    "lead": "Jack Nicholson",
    "genre_lead": "comedy_Jack Nicholson"
},...

Using this structure we can fetch movie, that has genre - comedy and whose lead actor is - Jack Nicholson.

Tip 8

There are no roles in Firebase. All authenticated accounts will only have email, password and uuid.  We can assign account roles using database.

Tip 9

If your firebase object has a nested object that can be empty in some cases, then it is better to delete this object completely along with the key, rather than keeping its key with an empty value. The reason of such an approach is that data snapshot parser on mobile side can work with a specified type, and if the specified type is different from the actual one, then it will crash. If there won’t be an object, then parse will return null. For example:

Show code

//Driver has car assigned
"driver": {
    "car": {
        "model": "Audi TT",
        "vin": "KL5TJ66E19B411947",
    },
    "first_name": "John",
    "last_name": "Doe"
},...


//Driver has no car assigned
//Bad practice
"driver": {
    "car": "",
    "first_name": "John",
    "last_name": "Doe"
},...


//Good practice
"driver": {
    "first_name": "John",
    "last_name": "Doe"
},...


As you can see in the bad practice case parser will have a driver object type with nested car object specified, but the actual type will be String. I’d like to point out that the summary of my Firebase experience is positive in common. But as everything else in our world, it has its own pros and cons.

Pros

At first I would say that the Realtime database is a very good alternative for the server when not developing complex apps, because it has everything that is necessary for this. And no doubt, the big plus is the callback system of data fetching. When something in database is changed, callback on mobile side is triggered immediately. Awesome right? 

Cons

But there is no substitution for good old RESTful serverside either. Sure it has no dynamic data update, but it can have the SQL DB, that is much stronger than NoSQL which is used in Firebase. Also it could have the complex login mechanism. And finally, do keep in mind that firebase has limitations for free accounts. If you want to have big amounts of data in DB, or register more than one project under one Firebase account you should make a purchase.

SEE MORE: