One of the big announcements of Google IO 2016 was Firebase. No longer "just" a database, the Firebase umbrella now includes integrated Analytics, Crash Reporting, Push Messaging, Dynamic Links, Storage, Hosting, and more. Is this new platform ready for all your projects? Should you spend time learning everything about it?

We like to keep on top of new technology at Novoda, so we decided to dedicate some time to explore the new Firebase. With a small team of four developers (two for iOS and two for Android) we took the idea of a chat application shown in most sample code and expanded it into a more feature-rich example. Today we want to share with you our findings and the demo app that was built during this exploration. Say hello to Bonfire!





Android, Google Play and the Google Play logo are trademarks of Google Inc.

The iOS app hasn’t made it through the app review process, but you can sign up to our beta

A sample app

We are releasing the full source code for Bonfire, together with this blog post. Play with the sources and experience what can be quickly built on top of the Firebase stack in a real-world app example. Because most sample apps out there are focused only on showcasing how to use Firebase, they often end up being too simplistic to be a real benchmark. We wanted to create a real example of what an application using Firebase might look like.

Bonfire features:

Real time chat organised into channels

Authentication using Google Sign-In

Channel names limited to one emoji on database level

Public and private channels

Any user can create a channel

Channel members can add and remove members of a private channel

Remote configuration of the order of channels in the channels screen

Invite users to the app with a customised welcome screen

Firebase as an architecture

One of the most exciting things about Firebase is the ability to use it across multiple platforms: Android, iOS and web. At Novoda we’ve been working to create apps with a consistent architecture across iOS and Android. Firebase fits very well with that approach. Despite some minor differences between the APIs, having a common basis for discussing our code encourages and enables cross-platform collaboration.

Database

Firebase started out as just a realtime database. Now this term is collectively used for the whole suite of tools. Though its name has slightly changed, Firebase Realtime Database (as it’s now known) remains a very impressive piece of technology.

Firebase Realtime Database is a cloud-hosted NoSQL database, and data is stored in a JSON structure. You can view the data in an online dashboard, which is really useful during development. Additionally, offline modifications and data synchronization are handled automatically across multiple platforms.

This gives you a fully functioning key-value store with data sync that requires only minimal setup.

#####Firebase Realtime Database Dashboard

In order to make your data structures scale it’s a common practice to create indexes to query. The issue is that at the moment this means executing two queries separately. One to retrieve the index and a second one to read the data at the index. As such, it would be great to have the ability to declare a composition of those two queries in a single operation.

An example found in Bonfire would be to query the list of channels a user has access to, and for each channel ID retrieve the channel info. We must handle this kind of query ourselves at the moment, which adds complexity in our code. This also makes it less efficient than if it were part of the Firebase query language.

Another downside is the lack of control over the offline and synchronisation behaviour.

As it stands now there is no control over conflict resolution when a sync happens. The ability to define a javascript function that is used to resolve conflicts would give back control to the developers and allow for more confidence in the service..

Access to key nodes is managed through a set of ”database rules”, which allow for powerful read-write access control and flexible data validation. This is not only crucial for security reasons; it is also very useful whilst developing your applications. Since in a Firebase backed app your database is essentially your API, you want to be able to ensure it is used consistently on different clients. With database rules preventing any not explicitly allowed interaction, you’ll be immediately notified if you try to write to the wrong place by mistake. This means you won't risk writing half your messages to messages and the other half to msgs because of miscommunication.

#####Firebase Realtime Database Rules

The database rules come with some limitations too. They can get quite complex even for our simple chat app. Luckily, the Firebase console contains a simulator where you can test access to specific nodes of your database.

The main issue with the database rules at the moment is the lack of feedback on the client side when a query fails validation. The fact that the only reply when a read or write rule has failed is “Permission Denied” is a great security practice. However, if the write permission is granted, a validation rule failure still sends “Permission Denied”, and this is often too vague to be helpful.

Being able to get some form of feedback from the data validation on the client side would be great. A possible solution could be adding tags with an error code to boolean expressions in the validation rule. Those codes could be sent alongside the error to the clients.

Analytics

Firebase Analytics automatically tracks a bunch of information about your users, such as location, device information, user engagement, and more. On top of that, there are multiple predefined events that you can use.

#####Firebase Analytics Dashboard

You can also define your own custom events. The difference we noticed between the two is that custom events are not displayed with all their details in the Firebase console. This means that you can't view parameters of your custom events or filter based on them.

For instance, we wanted to track the average length of messages sent in the app. We could log that a message was sent, but could not see the 'message length' value in the Firebase console.

However, there is a remedy for that: Firebase provides a handy integration with BigQuery, where you can get the full analytics data, including any custom parameters you have added. This particular feature is worth drawing attention to, since BigQuery allows in-depth analysis of both your analytics data and also external data in Federated data sources. This has tremendous potential for data analysis, custom dashboards, and visualisation of anything one can think of. Just look at what was acheived in this awesome Google I/O talk.

Crash reporting

Setting up Firebase Crash reporting is really simple and the basic setup automatically logs all fatal crashes without you having to do anything. Apart from that, it allows you to manually log non-fatal errors together with some custom additional information. If you are looking for more in depth analysis of the crash reporting go read this great post.

Authentication

#####Firebase Crash Reporting Dashboard

Firebase integrates very easily with popular authentication methods such as Google Sign-In, Twitter and Facebook. The authentication status can easily be used as part of the database access rules.

For example, the following code defines a user profile that only authenticated users can read and that only the owner can modify.

"$user_id": { ".read": "auth != null", ".write": "auth.uid === $user_id" }

#####Bonfire login screen on Android

Dynamic links are pretty cool! If your app is installed, they will deep link into it. If it’s not, they will take you the relevant store (App Store or Play Store). After the app has been installed, they’ll pass you the link. This has multiple uses beyond analytics tracking, as it allows you to deep link immediately after installation or provide custom onboarding paths into the app. Crucially, they are cross-platform, which means that you can generate links from iOS or Android that will deep-link into any platform.

#####Opening invite link when the app is not installed

Firebase also contains Invites, which are built on top of dynamic links and aim to make it easy to create invitation messages. This feature relies entirely on Google Sign-In and feels totally out of place on iOS. Therefore, to keep the UX as consistent as possible across both platforms, we decided to only use dynamic links.

Cloud testing

Unfortunately Test Lab features are only available for Android. Regardless, the Test Lab features for Android are really impressive and still worth looking into.

Firebase Test Lab for Android allows you to run your instrumentation tests in the cloud on a set of devices and API versions. On top of that, the lab contains a feature called Robo test. This could be described as a more intelligent monkeyrunnner which can traverse through your app automatically without you having to write the tests. It also generates a graph of your activities with the paths that it followed when moving between screens.

#####Activity graph created by Robo

For both instrumentation and Robo tests, Test Lab records a video of the screen, so you can watch the tests after they are finished. If all that is not cool enough, you can run the tests from Android Studio or from command line which makes it pretty easy to integrate with your favourite CI server.

Server-side logic

The ability to define some server-side logic would take Firebase from great to amazing. One of the biggest issues with a synced NoSQL database is that it requires each client to implement similar logic to handle things like indexes. Duplicating data is totally fine. Duplicating logic, on the other hand, not so much. What if you could write a single element to your database on the client, and update all the relevant indexes throughout the code in the cloud?

There are of course caveats around offline capabilities when over-relying on server side logic. If used correctly, though, they could greatly reduce the amount of client-side code that needs to be written on each platform and the risks that results from those implementations getting out of sync.

Drawbacks

Firebase looks great to kickstart a new project with a small team, but it is not perfect just yet.

Firebase depends on Google Play Services, which is a big issue if you have a project that you want to scale worldwide. A lot of users in China and other regions won’t be able to use your apps. In the Western world, Kindle Fire users will be excluded as well. In our opinion, this is a blocker to being able to use it as the base for most of our apps.

It should be possible for Firebase to abstract away the dependency on the Play Services and allow support for a wider range of devices. As an example, a library called Firebase Job Dispatcher uses the abstraction of a Driver to enable replacement of the default GooglePlayDriver with a custom implementation. A similar approach for replacing Play Services (even if it meant writing a fair bit of logic ourselves) would enable developers to truly rely on Firebase for their apps without reducing their ability to reach developing markets.

Google may never remove the dependency on Play Services as they have a clear vested interest in their adoption. However, we would like to believe that, like us, they can see the power and reach it would gain by doing so and that we will soon be able to use Firebase in any of our projects.

Another blocker that prevents us from using Firebase on larger projects is the lack of configuration management across projects. You can easily create a project for production and one for development, but then you need to sync your database rules, manage multiple URLs, etc. (cue headache).

The ability to have a production, development, or even short-lived testing environments where you could run tests would really take the platform to the next level.

Firebase does have the ability to give users permission to only certain parts of the console, but being able to completely switch off some features (e.g. deleting all the data in the database with just a couple of clicks) would help a lot.

Conclusion

Even if Firebase might not be ready for your large scale projects, we think that it is worth diving into it right now. You can always start small with only a subset of the available features, like Dynamic links and Remote configuration. Just the combination of those two on a legacy project is already rather powerful, especially considering how easy to implement they are.

In its current state, Firebase as a whole is great for small projects that are starting from scratch, and don’t mind the restriction to devices with Play Services. However, with a few adjustments from Google it truly has the potential to become the new backbone of most of the apps out there.

Now go on and have some fun with it!

Contributors:

Ben Augustin and Jozef Celuch for developing the Android side, Yvette Cook and Dominic Freeston for the iOS part of this app, Joe Timmins for helping us keeping things testable and a nice fresh perspective and Qi Qu for the amazing design work and everyone else at Novoda always contributing comments, ideas and suggestions.