Complete tutorial on how to plug Magic into Firebase Auth to access the full power of Google Firebase!
Magic works out of the box with Firebase - seamlessly connecting state-of-the-art, no lock-in identity and authentication to the immense power of the Google platform.
Setup Cloud Functions Project
This section is to help new developers who don't already have a project with Firebase Cloud Functions setup. If you already have an existing Cloud Functions project, feel free to skip to the Next Section!
1. Create a Firebase Project
In the Firebase console, click Add project, then select or enter a Project name.
Click Continue through the steps and then click Create project.
After a minute or so, your project will be created. Then continue to your project home page and enable the Firestore database feature.
Click on the Create database button and you will be directed through a short flow to complete the setup. Don't worry too much about the secure rules yet as we'll get to those later.
2. Setup Node.js and the Firebase CLI
Now that your project is setup. You'll need a Node.js environment to write functions and properly initialize your project locally, and you'll need the Firebase CLI to deploy functions to the Cloud Functions runtime. Node.js versions 8 and 10 are supported. For installing Node.js and npm, Node Version Manager is recommended.
Once you have Node.js and npm installed, install the Firebase CLI via your preferred method. To install the CLI via npm, use:
3. Initialize Firebase SDK for Cloud Functions
To initialize your project:
firebase loginto log in via the browser and authenticate the firebase tool.
Go to your Firebase project directory or create a new empty directory.
firebase initcommand to initialize your project.
Now you will see some options you'll be able to multi-select, pick both the Firestore and Functions options to be able to go through this tutorial.
After that you will be presented an option to Use an existing project, pick this option and select the project name you just created on the Firebase console.
Select Default or Yes to every step after to initialize the Firestore configurations.
Continue the steps and after the npm packages are installed, your project will be fully initialized and ready to go! 🔥
Connect Magic to Firebase Auth
Magic doesn't replace Firebase Auth, and can actually integrate seamlessly into it so you will be able to have the same permissions and database rules configurations as if it's native Firebase Auth. Before we go into writing the Magic + Firebase adapter Cloud Function, understanding the data flow on the front-end code will be very helpful.
Auth Data Flow
- User logs in in with Magic link, which upon successful login, generates a DID token
- The DID token is passed into the
httpsCallableCloud Function that we will be implementing in later section
authCloud Function takes in the DID token and converts it into a Firebase user access token
- Pass the Firebase user access token into the
firebase.auth().signInWithCustomTokenmethod to authenticate user natively with Firebase
Here's a sample front-end code snippet to implement this data flow:
Get Firebase Config
Setting up your Firebase front-end project properly can help avoid a lot of headaches later. Note that there's a
firebaseConfig configuration in our example source code. You'll be able to get this configuration in your project's settings view.
Navigate to settings for your project
Copy and paste this configuration to your front-end code
Implement Auth Callable Function
The Auth callable Cloud Function will be the crucial piece to converting a Magic DID token into a Firebase user access token to enable this entire experience. We'll go through the configuration steps first.
Configure and Initialize
1️. In your Cloud Functions file, you'll have to initialize Firebase with its admin SDK and your service account credential.
2️. Getting the service account credential is extremely important to make sure you have the right permissions to create the Firebase user access token. You can find it in your Project settings page, under the Service accounts tab, and then click on Generate new private key.
3️. After downloading the credential, you can put the
.json credential file into your project directory and update the path in the
const serviceAccount = require("./path/to/my-project.json"); line, as well as updating the
databaseURL to the one you see in your project settings dashboard.
These are your Firebase server side credentials, keep them secret!
After all the setup, now let's finally get to the fun part! 🎉 Essentially the
auth callable function handles authentication for two types of scenarios (1) existing users who already have email addresses set, including legacy Firebase users, and (2) create new users based on their email addresses and DID token generated by Magic. This callable function will return a unique Firebase user access token and pass it back to the client.
This is a sample implementation on how you can implement this auth function based on those two scenarios via two handler functions:
The existing user handler function takes in the existing user object from Firebase and the claim from the DID token to check for replay attack, and if successful, generates and returns a valid Firebase user access token.
The new user handler function takes in the email and creates a new Firebase user based on it, and then generates and returns a valid Firebase user access token.
You can find the complete auth callable function project on our GitHub.
Configure Firestore Rules
After you've implemented the
auth callable function, go to the
firestore.rules file in your local project directory and update it with the following - essentially only allowing the currently authenticated user to perform CRUD in the
Deploy to Firebase
Now you can simply run the following command with the Firebase CLI in your project directory to deploy your code to Firebase! 🎉
If you are seeing an error like below in your Firebase Cloud Functions log, it's because Firebase requires project Billing to be configured before enabling access to external networks.