In the previous posts, I tried to highlight the best (and worst :)) parts of using Firestore. I talked about ergonomics and outstanding libraries for all major mobile platforms. I also mentioned that Firestore might be problematic sometimes. Unpredictable latency, hard-to-maintain security, no validation, and crazy pricing are just some of the offenses.
Now, I want to talk about a different case. What if you’re already using Firestore, but you’re starting to feel all the pain connected to it? Is it all lost? Do you need to bear the burden ‘till the end of time? Are there ways to get out? I will once again use my favorite consultant-ish sentence that is so valid - it depends.
This is the final article from a series where we comprehensively describe the pros and cons of using Firestore as the backend solution and database for your next mobile or web application. In this series, we try to show you that making this decision is not a simple process, and you need to analyze your app from multiple perspectives.
Posts in the series:
Would you like to learn what to do when you’re already using Firestore but are unhappy with it? Read on to find out why!
This happens to everyone. Firestore seems like a perfect fit for your use case. You select it, start working on the app and maybe even publish the first version. Then, bad things happen.
This is normal, really. There is nothing wrong with it. You might not have been aware of the limitations that I’ve shown in part II. Or you just didn’t expect it would ever be a problem. Firestore looks like a database without any gotchas. We also did fall for it.
There are other possibilities. Suppose you’ve created a small MVP to validate business hypotheses. It worked great, but now you need to move on, and you are aware that Firestore will make your life more difficult than it should be, so you want to get rid of it (or at least minimize the usage). This is a very healthy scenario - it allows you to start fast & small, and now you make informed decisions. Kudos!
As you can see, using Firestore isn’t inherently bad. It works for some cases, but you need to know when to withdraw and… pivot.
I feel you. We put some (not that much, fortunately for us) data in Firestore and had to move it out. There are at least a couple of approaches for this procedure, but none of them is perfect.
You can think of “escaping” in terms of “escaping a particular version of data.” You can use the same techniques to upgrade your data model between versions or change it altogether.
This is the easiest of all. Unfortunately, it requires you to schedule downtime and forces your users to update the app. Otherwise, they won’t be able to use it.
You basically select a period when you shut down your app. During that time, you publish a new app version and migrate all necessary data out of the Firestore. Depending on the amount of data and luck, it might take between hours and (in the worst case) days. Your app will be completely unusable for most of the migration period, and even if you finish it, some users won’t be able to download the new version just yet.
Also, this approach requires you to have force update mechanisms in place. It would also be great if you could block the write side of the app (that can be done with Firestore authorization rules, but that will result in a suboptimal user experience), just in case.
This is by far the easiest approach but one that is really disruptive to your app. If your users are active, you will have difficulty justifying this. Also, if anything goes wrong during the migration, the process might be much longer than initially expected, which will anger your users even more.
This variation on the big bang deployment would require no downtime. You do mostly the same things as with big bang, but instead of disabling the old app, you put it in read-only mode. It would help if you also nudged your users to update the app, but now you don’t need to force them to update.
The main problem is that some of your users might not want to update, and being unable to change anything might not be enough to force them to. This means that you need to sync the data back to Firestore. Depending on the size and complexity of your app, this might require you to write quite a substantial amount of additional code (that, in the end, will be deleted), so it might be more costly compared to downtime.
We did this in one of our projects (where Firestore was used as a database of server-generated data). The data was read-only right from the beginning, so we had a somewhat simpler case - we hadn’t shut down the app. It worked great, and no one noticed, maybe apart from the fact that the new version worked much faster.
You can extend the previous approach and sync the data from the new store to the old one and the other way around. This way, your old app would work uninterrupted. It also means that you need to continuously sync the data between two, possibly quite different, storages.
If you have any business rules that require consistency, you will have a hard time enforcing them - what if two users using different app versions try to do the same action simultaneously? Both will win because one won’t know about the other, and optimistic concurrency won’t help here. This makes the approach very hard, requiring much thought to work correctly.
On the other hand, it might be the safest way to do a migration. Everything is done during an extended time, probably with multiple intermittent deployments, so you will have multiple occasions to fix the inevitable bugs.
In this series, I tried to show you first the good parts of Firestore (and Firebase). It is a fantastic technology that offers quite a few features and works perfectly within all Android, iOS, React Native, Flutter, and Web apps. It tries to solve a pretty broad set of problems but is only well-suited for some. I told you what are my favorite drawbacks in part II.
Security, latency, and pricing are only the most important things you need to know about and workaround in your app. For us, these drawbacks make Firestore unsuited for most of the projects out there. It might be used selectively, only in some parts of the system, but it can’t be your core solution to everything
There are no problems that can’t be solved or worked around. I tried to explain that in the previous part. Not every solution will work. Some of them require you to adjust the critical path. Some degrade UX. This is all about tradeoffs that, unfortunately, are prevalent if you choose Firestore.
Not everything is lost. In this part, I’ve shown you how you can end up in a bad place - and there is nothing wrong with being in a bad place. You need to admit it and move on. Replacing Firestore might be a challenging, long-lasting endeavor, but it is achievable.
And you can always ask us for help.
What a ride. This series. I had so much fun writing this. At first, I didn't expect to go for more than a few paragraphs. It turned out to be almost an 18-pager, my most comprehensive article (series) to date and, I think, my longest one for the coming years. I hope it did help you decide whether Firestore is a good fit for your use case. And you have enjoyed reading it!
‘Till next time!