I built my portfolio website jamesinkala.me over a year ago (james-sinkala.netlify.com/app before switching to the custom domain), and at the time while looking for a database client to store data I opted for Firebase’s Cloud Firestore as it is one of the best options around, add on top the fact that it’s owned by Google so it’s fair to expect everything to be top notch.
Despite the good such as real-time data, speed in implementing it and a plethora of features I found it lacking in some use cases and was disappointed that it couldn’t be spot-on on them where I preferred databases such as Fauna in place of it. I personally made the switch from firebase to Fauna after dealing with these bottlenecks that ultimately tested my patience.
Fauna is a server less global database designed for low latency and developer productivity. Among the best aspects about Fauna is it’s query language FQL(Fauna Query Language), which has been designed with low latency and productivity in mind. With it, you can create expressive queries that will allow you to harness the full power of Fauna.
In the following assessment, I’ll be presenting the challenges that I faced while using Firebase’s Cloud Firestore that later led me to ditching it in favor of Fauna.
Bundle Size
Using the Firebase npm module in a Javascript app substantially increases the total bundle size, in figures it’s 809kb compared to only 56.5kb when you use the Fauna npm module. This generally contributes to slow loading times and subsequently affects the overall user experience in your app. Surprisingly it has been an issue for a while amongst developers using Firebase and personally was the first issue that pushed me towards looking into other NoSQL databases that in turn have more bundle size friendly modules as I have been working on web projects for a large part of the last two years.
It is astonishing that Firebase or Google rather is reluctant to work towards making the module less bundle hungry than it currently is, regarding the fact that they provide tools such as Lighthouse and PageSpeed Insights. I guess they should be at the front lines when it comes to creating modules or plugins that would pass the standards that they hold in high regard.
The screenshots below demonstrate the size differences between the Firebase modules and that of Fauna analyzed on https://bundlephobia.com at the time of writing this article.
Even the Cloud Firestore component of the Firebase JS SDK is still almost six times larger than Fauna’s npm module total size at around 313.1kb, which furthermore per instructions is still not intended for direct usage, and should only be used via the officially supported Firebase package, which gets us back to square one, 809kb.
Downtime
I had not noticed this issue until after I had directed a potential customer to my website after marketing my expertise. When I never heard back from him, I visited my website to up my self-esteem, but there was only a blank page where I had expected to see the grid of my previous work. Well, that was the kill blow for me. I had to switch to another NoSQL database service in this case Fauna, a service I had been using in some hobby and light production projects up to that moment.
At the same span of time (early October) most Google services seemed to have issues but I couldn’t see anything that reflected it on the official status pages, it might have been a regional issue or something but I could care less as that was it for me.
Doing a bit of research after I had switched to Fauna to relate the reported statuses of the two services on statusgator.com, my choice was still vindicated and it seemed there had been issues with Firebase even earlier than I had noticed, as I had been using the service on my website from mid 2019.
Simplicity
When looking for simplicity while setting up your database not wanting to spend much time understanding the user interface before using it then Firebase isn’t your choice, this is true especially for first time users.
Setting up Cloud Firestore in Firebase is tricky, as one needs to initially create a new Firebase project, then go on to setting up a couple of other things. When Firebase has finished setting up the project, you are presented with a couple of other tools Cloud Firestore being one of them. Here’s when you proceed to creating a database which involves more steps at this point than one would in creating a Fauna database.
In contrast, the people at Fauna have taken simplicity very seriously on the overall user experience. On first time registration, the user is presented with the database management page, with a simple UI, a “New Database” button centered and helpful resources just below that. Even without much assistance one can create a database and set up collections, indexes, functions and more in the proceeding pages. This makes the database setting up process less of a task than it needs be and more focus and time to be placed on working on your project.
Documentation
There is something about Firebase’s documentation site that makes it rather overcrowded than those of Fauna and Netlify, two services whose documentation I enjoy consuming. Customer/developer experience I would guess wasn’t at the forefront when they were designing it, piling up everything to do with Firebase on that side navigation, space real-estate seems to be quite expensive and the designers had decided to go cheap on it.
I think they should have broken the documentation website into individual services, that would have reduced the obfuscation. There is the case of the layout, the state where everything is thrown into the same side navigation, compressed together that has an effect of one not finding the reading experience not being comfortable, especially when spending too much time on it. This might be a personal thing but the mere fact that I fancy it less chances are the feeling might be mutual to a couple of other developers.
Even though Google has tried to be consistent in trying to design everything within their material design concept, I’m not a big fan and that might add to the effect the documentation has on me.
In addition, for several features I almost always feel the need to read the documentation then go through a video tutorial to quite grasp and apply whatever it is I want to implement effectively without going through hurdles. Sometimes I’d rather go through tutorials by other developers on features then only use the documentation when I really need to add to what I already know.
Learning Curve
Fauna has a gentle learning curve to Cloud Firestore. Not to interpret this into Firebase having quite a steep one but I could implement so much within the Fauna setup from the first time I read it’s docs. This may possibly be connected to how intuitive the documentation may be but more than that I could use and apply the FQL even before grasping how it fully works. I was able to set up a database and query data from it in short understandable lines of code in a project soon after reading a fair bit of Fauna’s docs. It was generally simple to get into the hard-core stuff just 30 minutes into consuming the documentation.
Using the fauna-shell client further simplifies setting up things such as databases, collections and indexes, all done from your terminal and involving the same syntax that you work with while using the FQL. Once you get the grip of Fauna’s query language everything becomes simple from setting up collections, creating and updating documents, setting up indexes to using user defined functions within the database queries.
You can probably set up collection indexes even without consulting documentation about it as I was initially able to. This might be due to the large resemblance between Fauna and SQL databases which is always a plus as most developers delving into NoSQL databases are likely to have that background more than not.
For instance, the FQL’s Lambda() function comes quite handy when formatting fetched documents in place of references without the need to loop through initially fetched responses to map out desired arrays.
In the following FQL code we are fetching a list of students from the “all_students” index and are returning the desired array of documents without having to do that with our programming language later after receiving the response.
Map(
Paginate(Match(Index("all_students"))),
Lambda("student", Get(Var("student"))) // processed within request
)
The same task in Firestore would require us to loop through the response data in order for us to create our desired final array:
var allStudents = [];
var students = db.collectionGroup('landmarks')
students.get().then(function (querySnapshot) {
// processed after having received the response
querySnapshot.forEach(function (doc) {
allStudents.push(doc.data());
});
});
When you combine FQL’s Lambda(), Let() and Select() functions, tasks get more powerful with less code.
In the following FQL syntax, we query for students from the “all_students” index while specifying the data that we need to have returned inside the response.
Map(
Paginate(Match(Index("all_students"))),
Lambda("studentRef",
Let(
{
studentDoc: Get(Var("studentRef"))
},
{
id: Select(["ref", "id"], Var("studentDoc")),
name: Select(["data", "name"], Var("studentDoc")),
age: Select(["data", "age"], Var("studentDoc"))
}
)
)
)
While in Firestore the same logic as demonstrated above would include first making a request to a collection or index then secondly looping through the response data to construct our desired final data.
var allStudents = [];
var students = db.collectionGroup('landmarks')
students.get().then(function (querySnapshot) {
// processed after having received the response
querySnapshot.forEach(function (doc) {
allStudents.push({
id: doc.data()._id,
name: doc.data().name,
age: doc.data().age
});
});
});
I am definitely still going to use firebase in the future, especially when developing real-time apps such as chatting apps and the like, mainly in cases that involve a mobile app setup, since in such cases I think Firebase’s Firestore and Realtime databases are superior and you don’t look much into the bundle size when it comes to such scenarios but functionality.
In cases where real-time data updates aren’t of importance, such as on portfolio, directory, blog or even e-commerce websites where the total user experience has to be top notch and conversions are directly related to page load times such as in the case of e-commerce websites, firebase is an overkill and per the few experiences I’ve had with it, it’s a liability.
I personally will continue to use and would advise any developer to use Fauna in the specific cases I have listed above since it’s simplistic and efficient as it’s a database designed for low latency and developer productivity. It brings about the familiar SQL feel for developers that have worked with SQL databases previously and learning to use and working with FQL will be a treat. On top of that for those that like to work with GraphQL they will feel at home with the Fauna GraphQL API.
Top comments (4)
I made the switch myself, and and love Fauna for it's simplicity.
Though I still believe they should invest in great learning material (courses or online modules). I still struggle a lot joining collections. Right now I have a use case, where I would like to join other collections, but it is hard to find any good documentation or guide on how to do it with multiple collections.
Perhaps you James could write another great article on the subject? :)
While I prefer Fauna over Firebase 1000x, the bundle size comparison is not correct.
On the browser, the Fauna driver requires polyfills from NodeJS to be able to work which makes it about 48kB gzip (178kB minified).
See for yourself: cdn.jsdelivr.net/npm/faunadb@4.0.0...
Also, the Firebase package you used for the comparison includes everything (auth, db, storage, etc). If you only take into account the realtime DB driver it weights around 51kB:
bundlephobia.com/result?p=@firebas...
I appreciate you giving in more insight. My bad for not making the post a bit longer but I was using auth, db and storage within my previous setup. Currently I use fauna for the database, have setup a simple authentication within my app without adding any dependency, I host my images on cloudinary and control the image management through a single Vue component, where with this new setup I've cut back on bundle size compared to the firebase setup. But also as you pointed out above unless I haven't grasped it correctly even with the polyfills the amount that fauna adds to the bundle size is a bit short of that of firebase's database driver alone.
Yeah it's a bit smaller but the difference is negligible when both are so heavy.