Migrating Users from Firebase

Migrating your users from one auth source to another can seem scary. Fortunately, we're here to help! See our Migrating Users to PropelAuth guide for more general information or stay here for an advanced guide, including code snippets, on how to migrate your users from Firebase to PropelAuth.

Exporting Users from Firebase

You can easily export a JSON of your user data from Firebase using the Firebase CLI. You can install the Firebase CLI by using the following command in your terminal:

npm install -g firebase-tools

Next, run the login command. This will open up your browser and connect your local machine to your Firebase account, granting you access to your Firebase projects.

firebase login

We then need to retrieve the Project ID of the project you're exporting. Run this command, find the correct project, and copy the Project ID.

firebase projects:list

Lastly, we can export your users by using the auth:export command. You have the option to adjust the name of the export as well as the format (CSV or JSON), but for this example we'll be naming the file firebase_user_export.json and export in JSON format. Make sure to replace {YOUR_PROJECT_ID} with the Project ID you retrieved in the previous step.

firebase auth:export firebase_user_export.json --format=json --project {YOUR_PROJECT_ID}

We now have a JSON file of your user data! Next, we'll start the process of importing these users into your PropelAuth project.

Retrieving Your Password Hash Parameters

While the user export we just created includes your user's hashed passwords, we need a bit more information in order to import these passwords into PropelAuth.

Log into your Firebase account and navigate to the Authentication menu located in the left navigation bar. Make sure you're viewing the Users tab, then click on the three dots towards the right side of the screen. Then, click on Password hash parameters.

firebase password hash parameters

This will display a config like so:

hash_config {
  algorithm: SCRYPT,
  base64_signer_key: z6EeR...,
  base64_salt_separator: Bw==,
  rounds: 8,
  mem_cost: 14,
}

Copy down each value. We'll be using these values in the next step of importing our users into PropelAuth.

Importing Users into PropelAuth

We can now use firebase_user_export.json to import your user data to PropelAuth. PropelAuth offers an API endpoint to make migrating users as simple as possible. Before we run the script, let's install PropelAuth's Python library:

pip install propelauth_py

This script will attempt to import each of the users found in your firebase_user_export.json file into PropelAuth. If any of the imports fail, it will automatically generate a ./unmigrated_users.json file for you.

To run the script we need to get your PROPELAUTH_AUTH_URL and PROPELAUTH_AUTH_API_KEY, both of which can be found in your Backend Integration page in PropelAuth. We'll also be using the Firebase password hash parameters that we retrieved in the previous step.

from propelauth_py import init_base_auth
import json

# Replace with your PropelAuth Auth URL and API key
PROPELAUTH_AUTH_URL = "https://auth.yourdomain.com"
PROPELAUTH_AUTH_API_KEY = "b1988511..."

# Replace with your Firebase Password Hash Parameters
SIGNER_KEY = ''
SALT_SEPARATOR = ''
ROUNDS = ''
MEMORY_COST = ''

# replace with your JSON path
firebase_json_filename = "./firebase_user_export.json"

# If we fail to migrate any users, we'll output them here
unmigrated_users_filename = "./unmigrated_users.json"

auth = init_base_auth(PROPELAUTH_AUTH_URL, PROPELAUTH_AUTH_API_KEY)

def create_propelauth_user(user_data):
    auth.migrate_user_from_external_source(
        email = user_data.get('email'),
        email_confirmed = user_data.get('email_confirmed'),
        existing_user_id = user_data.get('id'),
        existing_password_hash = user_data.get('password_hash'),
        ask_user_to_update_password_on_login = False,
        enabled = True,
        username = user_data.get('username'),
        first_name = user_data.get('first_name'),
        last_name = user_data.get('last_name'),
        properties = user_data.get('properties'),
    )
    print(f"API call successful for user: {user_data.get('id')}")

def process_users():
    users_with_errors = []
    
    with open(firebase_json_filename, "r") as firebase_json_file:
        user_data = json.load(firebase_json_file)
        # Iterate through each user row
        for user in user_data["users"]:
            try:
                user_migrate_data = {
                    'id': user.get('localId'),
                    'email': user.get('email'),
					'email_confirmed': user.get('emailVerified'),
                    
     
                    # Fields below this are dependent on your setup, you may need to modify
                    #'first_name': row.get('Given Name'),
                    #'last_name': row.get('Family Name'),
                    #'username': user.get('displayName'),
                    # Any custom user properties that aren't first_name, last_name, or username go here
                    #'properties': {
                    #    'sample_custom_property': row['sample']
                    #}
                }
                
                if user.get('passwordHash'):
                    user_migrate_data['password_hash'] = f"$firebase${SALT_SEPARATOR}${SIGNER_KEY}${ROUNDS}${MEMORY_COST}${user.get('salt')}${user.get('passwordHash')}"
                
                create_propelauth_user(user_migrate_data)
            except Exception as e:
                users_with_errors.append(user)
                print(f"Error during processing user: {user['Id']}")
                print(f"Error: {e}")

    if len(users_with_errors) > 0:
        with open(unmigrated_users_filename, "w") as unmigrated_users_file:
            for failed_user in users_with_errors:
                unmigrated_users_file.write(json.dumps(failed_user) + "\n")

        print(f"We couldn't migrate all users - the users we failed to migrate are here {unmigrated_users_filename}")

# Run the script
if __name__ == "__main__":
    process_users()

Need a do over? Here's a script to quickly delete all of your users so you can try again.

import requests
from propelauth_py import init_base_auth

# Replace with your PropelAuth Auth URL and API key
PROPELAUTH_AUTH_URL = "https://auth.yourdomain.com"
PROPELAUTH_AUTH_API_KEY = "b1988511..."

auth = init_base_auth(PROPELAUTH_AUTH_URL, PROPELAUTH_AUTH_API_KEY)

def get_users():
    try:
        response = auth.fetch_users_by_query(
            page_size = 10,
            page_number = 0
        )
        return response
    except requests.exceptions.RequestException as e:
        print(f"Error making API call to retrieve users")
        print(f"Error: {e}")

def delete_user(user_id):
    try:
        auth.delete_user(user_id)
    except requests.exceptions.RequestException as e:
        print(f"Error making API call to delete user {user_id}")
        print(f"Error: {e}")

def delete_users():
    user_response = get_users()
    while len(user_response['users']) > 0:
        for user in user_response['users']:
            delete_user(user['user_id'])
        user_response = get_users()

# Run the script
if __name__ == "__main__":
    delete_users()

All of your users are now imported! If you run into any problems, do not hesitate to reach out to support@propelauth.com.