Handling Providers Linking Operations and Identifiers Updates with drf firebase auth - agence-courrier/drf-firebase-auth GitHub Wiki
The project app transporaphobia relies on Firebase for authentication and it is a combination between the Firebase JavaScript SDK Firebase JavaScript SDK and the Firebase Admin SDK which uses Python.
In order to fast skip development using Firebase Admin SDK with Django, we decided to use drf-firebase-auth. It is directly implemented with Django and can be used as the default authentication class and it is well maintained.
Technically, drf-firebase-auth is a Django app and according to the settings we have set up, drf-firebase-auth workflow can presented in the following diagram:
For each HTTP request from the client front-end to the back-end, the above process would happen. Still, drf-firebase-auth cannot handle one special case. This special case is when an identifier is updated on the Firebase Users Table during an account linking process or an update to a new email.
If the email has been updated through an account linking; then, in STEP 6 on the diagram the SELECT statement will not find a User with the newly updated email that was returned as a result of the decoded token. This will result us to go to step 7; inserting a Firebase ID into the username field in User model. But, the username field is set to unique and this won't let us insert the same username since we are using the same account, this would result in a SQL UNIQUE constraint
error. In other words, the error occurs in Step 7.
This means that some account linking operation that are performed would definitely result in such error. The following diagram explains in which condition this error would occur:
As shown in the diagram because the Facebook had an email identifier and was linked to an email provider, then, the email provider identifier will replace the Facebook provider identifier; again this is because Facebook had an email as an identifier. But, the User model would still assume that Firebase hadn't changed the email.
In order to give a correct solution for the problem we must change the behavior of Step 6 in the diagram shown in the Data Flow section, in order to avoid the error in Step 7. We must SELECT the User based on his Firebase ID, not his email. This is because the Firebase ID is immutable in both the Firebase Users Table and in the User model, it is also a unique ID. While the identifier is immutable, it can have more than one value; eg. it can be represented as an array containing an email and a phone number). The following diagram show case that the modification we've made are in Step 6:
In order for this new version to work successfully, the username must be filled with the Firebase ID. This means that the only function that would work is map_firebase_uid_to_username
, which is the default function. All other functions are going to be deleted in order to avoid ambiguity and any error. FIREBASE_USERNAME_MAPPING_FUNC
would also not be needed to be declared in the project.setting
file.