When we started Pocketcoach in 2019, we chose to host all our data in the US. As I set up the Firebase project needed for our react native mobile app, I didn't give too much thought to the range of options I was presented with. Amongst other things, a user has to choose where their servers will be located for the project. Our users would mostly be located in the US—or so we thought at the time—so hosting our data there made perfect sense. I recommend that you closely examine where your service will be located before you create a project. You can find more detailed information about setting your location here.
Two years later, we decided to focus much more on the German-speaking DACH area (Germany, Austria and Switzerland). For a range of legal reasons, including the recent privacy shield judgement, and with data privacy laws being much more strict in the DACH area, we decided to also move our data to servers based in Europe.
Initially, I thought this would be relatively simple. I’d probably just need to flick a switch somewhere in the project settings.
However, when I examined these settings more closely, I didn't find anything. Then I stumbled upon this:
It was bad news. As it turns out, you can’t change the location on your Firebase Firestore and other default locations once they are set.
I immediately contacted the Firebase support team, who informed me that the best course of action was to create a new project with the new location and then migrate over all my services. Oh boy!
We were running our app and using a whole bunch of Firebase services, including:
- Notifications (Firebase Cloud Messaging)
- Database (Firestore)
- Cloud Functions
After some thought and tinkering, we developed a plan to migrate over all our services with limited disruption to our users. If you find yourself in the same situation, here are the four steps we took to make the transition as seamless as possible.
Step 1 - Create new project with the correct settings
When you set up your new project, pay close attention to the settings and locations you select. Remember, you will not be able to change the location later on, so make sure you choose the right one this time.
Step 2 - Get your app up and running with the new project
Getting your app up and running involves migrating all of your Firebase services and data. Here is how we did it:
If you are using cloud functions, don’t forget to deploy them to your new project. If you are deploying them from your computer via console, you will need to change your private key file. You can download it from Project Settings > Service accounts > Firebase Admin SDK
Change your Firebase keys the App is using itself
For Android download the new google-services.json from the project settings page
For iOs download the GoogleService.plist from the project settings page
For iOS, simply add the Auth key you used for your old project.
For Android, this will be a little bit more tricky because only one project can be connected to your app at any given time. Don’t worry, I’ll show you exactly how to handle this later in this post.
If you also want to move authentication (which I strongly recommend as it will mean you have all of your services in one project), the only practical solution we could find was to use the Google-provided CLI tool for exporting your authenticated users from one database and importing them to the other.
We did all of this before we made the app live and once again a day later to catch users who downloaded our old app but only registered after we did the first migration.
Step 3 - Create a cloud function that syncs user data
One problem you will certainly run into is that, at some point, all of your users will still be on the old database, but if you copy them over just once to the new database, users, who used the app between you copying the old to the new database, will lose data or encounter inconsistency when they update their app (which works with the new database)
Here is the solution that worked for us: We created a cloud function that connected to the old project and synced all of our user data to the new project. This cloud function was triggered one time, when the user first opened the new version of the app, which already works with your new firebase project.
Step 4 - Make the switch
Another problem we ran into was notifications. As I mentioned earlier, for Android apps, a key can only be used for one project at a time. We solved this by releasing the Android app, waiting one day, and then removing the key from SHA certificate fingerprints in the old project settings. We then added the SHA certificate fingerprints of the android app to the other (new) project. This way users might not receive notifications for one day, so if this is business critical for your App we recommend you explore other options. We contacted Google, and this was the way the recommended us to handle it, so I am not sure if there is a better way to do this, with less impact on notifications
By the time we had completed these steps, it was clear that the process of migrating data isn’t as daunting as it may appear from the outset. Once we created a plan and broke it down into several steps, we were able to migrate our data relatively quickly and easily. I do, however, recommend that you carry out extensive testing of your solution afterward, especially edge cases like registering and logging in. We were able to complete this migration within two weeks, and although we did have a handful of customers contact us about problems, it was a very small percentage. One option to decrease the impact even more would be to export and import users from step two several times (i.e., every day for a week). Overall, we’re happy with how quick and easy this Firebase migration process was for us at Pocketcoach, and we’ll certainly pay closer attention to the project setup options next time!