'Synchronize users created with Firebase Auth to my custom backend

I want to use Firebase Auth for my user login/registration process. Everything else should be handled by my own backend (spring boot app + postgres db).

Now I'm asking myself how I can synchronize a new created user to my user table in postgres. I thought about the following:

  1. REST call through client - Everytime I get a success event from the firebase sdk I call an additional request to my backend which sends uid, username etc.

Problem: What if my backend call fails but the register process was successful ? That would lead to an inconsistent state since (at least thats what I understanded) I can't easily rollback. That would lead to situations where a user can login into my app without my backend knowing the user. This would crash/ invalidate all my following queries (e.g. search after user xyz would lead to no result even though he/she exists)

  1. Check the existence of the user in the postgres database

Here I would query the uid from the database (which I got from the jwt) and create a new user if it doesn't exists in every incoming request.

Problem: The user query is a unnessecary overhead for every incoming request.

  1. Trigger with cloud functions - When I understood it right firebase auth is firing events when a new user is created in cloud functions. This could be used to make the external api call.

Problem: I dont know what happens when my external rest call fails at this point. Can I rollback the registration ? Will I be ever catch this event again ? I also proably would have an eventual consistency situation, since I dont know when the cloud function triggers. Furthermore I would prefer not to include cloud functions to my stack

Is there any way how I could do this in a transactional manner ? Did anyone else tried is using sth simular ?

Thanks for every help!



Solution 1:[1]

The easiest way is actually to not synchronize auth data, but instead decode and verify the ID token of the user in your backend code.

This operation is (by design) stateless, although Firebase's own backend services often implement a cache of recently decoded tokens to speed up future calls with the same ID token.

Solution 2:[2]

Apparently, I finally came up with a different solution:

  1. Register user per Firebase SDK (e.g. with email + pw method)
  2. Make a post-call to my own registration api including the resulting uid from the previous step and some metadata
  3. API creates a new user including a column with the UID + Fetches the firebase token of the user and adds an internal claim that references to the internal Postgres UUID via Admin SDK.
  4. Frontend gets the created user and hard refreshes (very important, since the previously fetched token won't contain the newly added claim !) the firebase token and verifies that it contains the token. If it does -> everything is cool, if not some oopsie happened :) That will require a request retry.

Later when you start your app you can just check if the passed token contains the custom claim, if not open the sign up/sign in page. Every endpoint except the one for registration should check if the claim is set. If not just forbid the request.

How to set custom claims: https://firebase.google.com/docs/auth/admin/custom-claims#set_and_validate_custom_user_claims_via_the_admin_sdk

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Frank van Puffelen
Solution 2 Ahmet Kazaman