Chrome Extension Guide: Firebase Authentication with Email Links
Introduction to Firebase Authentication in Chrome Extensions
In this post, we’ll be exploring the process of setting up a Chrome extension project and integrating Firebase for email link authentication.
Table of Contents
- Introduction
- Setting up the Chrome Extension Project
- Overview of the Authentication Flow
- Detailed Authentication Flow
- Conclusion
Setting up the Chrome Extension Project
Let’s begin by setting up our Chrome extension project using crxjs and Vite. Follow the steps below:
- Create a Project: Initialize a new project using Vite 2 by running
npm init vite@^2.9.4
. - Install CRXJS Vite Plugin: Install the CRXJS Vite plugin with
npm i @crxjs/vite-plugin@latest -D
. - Update the Vite Config: Update your
vite.config.js
file to include the crxjs plugin and the manifest file. Thevite.config.js
should look like this:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { crx } from "@crxjs/vite-plugin";
import manifest from "./manifest.json";
export default defineConfig({
plugins: [react(), crx({ manifest })],
});
- Create the Manifest File: Add a
manifest.json
file next to yourvite.config.js
file with the necessary Chrome Extension’s properties. Here’s a simplemanifest.json
structure:
{
"manifest_version": 3,
"name": "CRXJS React Vite Example",
"version": "1.0.0",
"action": { "default_popup": "index.html" },
"background": {
"service_worker": "src/background.js",
"type": "module"
},
"permissions": ["tabs", "storage"]
}
- Run the Development Build: Execute
npm run dev
to start the development build of your project.
For more detailed guidance, you can refer back to the original crxjs guide.
Authentication Flow
Here’s a simplified view of the email link authentication flow for a Firebase-enabled Chrome extension:
- User enters email on the Login Page.
- Firebase sends an email link to the user.
- User clicks the email link and is redirected back to the Chrome extension.
- The Chrome extension confirms authentication and grants the user access.
The following flow diagram represents this process:
Detailed Authentication Flow
Let’s break down these steps in detail.
Step 1: User Enters Email
This React component, LoginPage, collects the user’s email and sends a Firebase authentication link. The handleSubmit function sends the email link when the form is submitted. If the email link is successfully sent, a success message is displayed. If an error occurs, it’s logged to the console.
Here’s the code snippet for the LoginPage component:
import { useState } from 'react';
import { getAuth, sendSignInLinkToEmail } from "firebase/auth";
import styles from '../styles/LoginPage.module.css';
function LoginPage() {
// ... component state and event handlers here ...
return (
<div className={styles.container}>
{!isSuccess && (
<form onSubmit={handleSubmit} className={styles.form}>
{/* form elements here */}
</form>
)}
{isSuccess && (
<p className={styles.successMessage}>
Login email successfully sent! Please check your email.
</p>
)}
</div>
);
}
export default LoginPage;
Check the complete version on GitHub repository for more details.
Step 2: Firebase Sends an Email Link
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
// Your web app's Firebase configuration
const firebaseConfig = {
apiKey: import.meta.env.VITE_APP_FIREBASE_API_KEY,
// ...other firebase configuration values...
};
// Initialize Firebase
const firebase = initializeApp(firebaseConfig);
const auth = getAuth(firebase);
export { auth };
export default firebase;
Check the complete version on GitHub repository for more details.
Step 3: User Clicks the Email Link
The background.js
script captures the email link when the user is redirected back to the extension. It sends a message with the URL to the content script, notifying it of the URL change.
// background.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
// Handle "SET_EMAIL_FOR_SIGN_IN" message here...
});
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (changeInfo.url) {
// Check if URL is from the extension and handle authentication link...
}
});
Check the complete version on GitHub repository for more details.
Step 4: Extension Confirms Authentication
The UserProvider
component receives the email link and uses it to authenticate the user with Firebase. If authenticated successfully, the user’s data is stored in the UserContext
.
// UserProvider.jsx
import { createContext, useState, useEffect } from "react";
import { auth } from "../firebase";
import { signInWithEmailLink } from "firebase/auth";
export const UserContext = createContext();
export const UserProvider = ({ children }) => {
const [user, setUser] = useState(null);
useEffect(() => {
// Handle authentication state changes and messages from background.js...
}, []);
return (
<UserContext.Provider value=>
{children}
</UserContext.Provider>
);
};
Check the complete version on GitHub repository for more details.
Conclusion
Feel free to comment below if you have any thoughts or questions. Your input is highly appreciated!