Skip to main content

Integrate Firebase with Web3Auth SFA JS SDK

single factor authwebfirebasecustom authenticationevmWeb3Auth Team | 14 November, 2023

This guide will cover the basics of how to set up your Web3Auth SDK and Firebase account for the integration and provide you with the links on how to develop a basic web application on the blockchain of your choice.

Quick Start

npx degit Web3Auth/web3auth-core-kit-examples/single-factor-auth-web/sfa-web-passwordless-example sfa-web-passwordless-demo && cd sfa-web-passwordless-demo && npm install && npm run start

How it works?

Single Factor Auth SDKs allow for the integration of a single factor of authentication, such as social login, into your dApp. They are designed to be simple to use and can be integrated into your dApp with minimal effort, allowing you to directly use the Web3Auth Network for Wallet Management. This is one of the most common use cases of Web3Auth, however, it is semi-custodial in nature, since the key is custodial to the Auth Provider and the Web3Auth Network.

This diagram describes the relationship between the Web3Auth SDK and integrating application
  • The first step for the application is to get the user authenticated by a login provider(here, Google) and get the user's idToken.
  • Once the social login is successful, depending on whether the user has enabled Multi-Factor Authentication(MFA) or not, the key is generated.
  • If the user has not enabled MFA, we use the @web3auth/single-factor-auth SDK to retrieve the private key shares from the Web3Auth auth network nodes and reconstruct the private key.
  • If the user has enabled MFA, an error message is shown that the user has enabled MFA and in this case, they should be using the Web3Auth Plug and Play Web SDKs.

Prerequisites

  • For Web Apps: A basic knowledge of JavaScript is required to use Web3Auth SDK.

  • For Mobile Apps: For the Web3Auth Mobile SDKs, you have a choice between iOS, Android, React Native & Flutter. Please refer to the Web3Auth SDK Reference for more information.

  • Create a Web3Auth account on the Web3Auth Dashboard

  • A Firebase account to be used as a Federated Identity Provider.

  • A Google Developer account to be used as an Identity provider for Firebase.

Setup

Setup Firebase

Create a Firebase Project

  • Create a new project by clicking on Add project or use your existing project from Firebase console.

    Firebase Project - Set up 1

  • Give your project a name and click on Continue

    Firebase Project - Set up 2

  • Finally, click on Create Project

    Firebase Project - Set up 3

Select Authentication Provider

  • Once the project is created. Set up authentication by clicking on the Authentication card from the home screen of your project or choose Authentication under Build from the left sidebar.

    Firebase Project - Set up auth 1

  • From the Sign-in method tab, select any provider you wish to enable. For this guide, we'll be enabling Google.

    Firebase Project - Set up auth 2

  • Finally, toggle the enable button and click on Save

    Firebase Project - Set up auth 3

Configure Firebase for Web

  • Once the project is created and authentication is configured. Let's use Firebase for Web by clicking on the </> button on the home screen of your project.

    Firebase Project - Set up web 1

  • In the next screen, enter the App nickname and click on the Register button to register the app for Web.

    Firebase Project - Set up web 2

  • The next screen shows ways to add Firebase to your application. We will be using the config from here later in the guide. Please keep a note of the firebaseConfig object.

    Firebase Project - Set up web 3

Setup Web3Auth

Setup Web3Auth Project

  • Create a Project from the Project Section of the Web3Auth Developer Dashboard.

    Plug n Play Project Creation on Web3Auth Dashboard

    • Enter your desired Project name.

    • Select the Product you want to use. For this guide, we'll be using the Plug n Play product.

    • Select the Platform type you want to use. For this guide, we'll be using the Web Application as the platform.

    • Select the Web3Auth Network as Sapphire Devnet. We recommend creating a project in the sapphire_devnet network during development. While moving to a production environment, make sure to convert your project to sapphire_mainnet or any of the legacy mainnet network mainnet, aqua, or cyan network. Otherwise, you'll end up losing users and keys.

    • Select the blockchain(s) you'll be building this project on. For interoperability with Torus Wallets, you have the option of allowing the user's private key to be used in other applications using Torus Wallets (EVM, Solana, XRPL & Casper).

    • Finally, once you create the project, you have the option to whitelist your URLs for the project. Please whitelist the domains where your project will be hosted.

      Plug n Play Project - Whitelist

Setup Firebase Custom Authentication Verifier

Create a Firebase Verifier from the Custom Authentication tab of your Web3Auth Project.

  • Click on the Custom Authentication tab of your Web3Auth Project.

  • Click on the Create Verifier button.

  • Enter a name of your choice for the verifier identifier. eg. w3a-firebase-demo

  • Select Custom Providers from the Choose a Login Provider section. Verifier Modal on Web3Auth Dashboard

  • JWKS Endpoint: Enter https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com as the JWKS endpoint for the Firebase.

  • Now you have the option to paste a sample idToken(JWT) to get the fields for the JWT validation. This step is optional, but if you have a sample JWT you can paste it here to get the fields for the JWT validation. You can also skip this step and fill in the fields manually.

  • The following are the JWT validation fields needed for the Firebase JWT validation:

    • Type iss as a field and https://securetoken.google.com/FIREBASE-PROJECT-ID as a value.
    • Next, type aud as a field and FIREBASE-PROJECT-ID as a value.

    Note: Replace the FIREBASE-PROJECT-ID with your Firebase Project ID.

  • Next, Select Sub, Email or a Custom value from the dropdown for the JWT Verifier ID. This is the field that will be used as the verifier ID for the user, and it has to be unique for each user.

  • Finally, Click on the Create button to create your verifier.

Verifier Modal on Web3Auth Dashboard

It may take up to 10 minutes to deploy the verifier on sapphire_devnet. You'll receive an email once it's complete.

Using the Web3Auth SFA JS SDK

To use the Web3Auth SFA JS SDK, you need to add @web3auth/single-factor-auth to your project.

Setting up your base project for using Web3 libraries:

If you are starting from scratch, to set up this project locally, you will need to create a base Web application, where you can install the required dependencies. However, while working with Web3, there are a few base libraries, which need additional configuration. This is because certain packages are not available in the browser environment, and we need to polyfill them manually. You can follow this documentation where we have mentioned the configuration changes for some popular frameworks for your reference.

Installation

For this project, you need to add the following Web3Auth dependencies to your package.json

npm install --save @web3auth/single-factor-auth @web3auth/ethereum-provider @web3auth/base web3 react-firebase-hooks/auth firebase

Understanding the Dependencies

@web3auth/base

Since we're using typescript, we need the @web3auth/base package to provide the types of the different variables we'll be using throughout the app-building process. This reduces errors to a very large extent.

npm install --save @web3auth/base
@web3auth/ethereum-provider

This package is used to provide the Ethereum provider to the Web3Auth SDK. This is required to interact with the blockchain.

npm install --save @web3auth/ethereum-provider
@web3auth/single-factor-auth

This package is the core package for Single Factor Auth JS SDK.

npm install --save @web3auth/single-factor-auth
react-firebase-hooks/auth

The react-firebase-hooks/auth package provides a convenient useAuthState hook for easily managing authentication states in React applications using Firebase.

npm install --save react-firebase-hooks/auth
firebase

This package is used to initialize the app with Firebase SDK and get the auth object.

npm install --save firebase
web3

This package is used to interact with the blockchain.

npm install --save web3

Setting up the Firebase config

To use the Firebase SDK, we need to configure the firebaseConfig object using the data we got from the Firebase console.

src/FireBaseConfig.ts
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";

// Your web app's Firebase configuration
const firebaseConfig = {
apiKey: "AIzaSyB0nd9YsPLu-tpdCrsXn8wgsWVAiYEpQ_E",
authDomain: "web3auth-oauth-logins.firebaseapp.com",
projectId: "web3auth-oauth-logins",
storageBucket: "web3auth-oauth-logins.appspot.com",
messagingSenderId: "461819774167",
appId: "1:461819774167:web:e74addfb6cc88f3b5b9c92",
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);

const auth = getAuth(app);

export { auth };

Initialization

Once installed, your Web3Auth application needs to be initialized. Initialization is a multi-step process where we add all the config details for Web3Auth SDK:

Importing the packages
import { Web3Auth } from "@web3auth/single-factor-auth";
import { CHAIN_NAMESPACES } from "@web3auth/base";
import { EthereumPrivateKeyProvider } from "@web3auth/ethereum-provider";
import { signInWithEmailLink, isSignInWithEmailLink, sendSignInLinkToEmail } from "firebase/auth";
import { auth } from "./FireBaseConfig";
import { useAuthState } from "react-firebase-hooks/auth";
Instantiate the Web3Auth SFA JS SDK
import { Web3Auth } from "@web3auth/single-factor-auth";
import { CHAIN_NAMESPACES } from "@web3auth/base";
import { EthereumPrivateKeyProvider } from "@web3auth/ethereum-provider";
import { signInWithEmailLink, isSignInWithEmailLink, sendSignInLinkToEmail } from "firebase/auth";
import { auth } from "./FireBaseConfig";
import { useAuthState } from "react-firebase-hooks/auth";

const clientId =
"BPi5PB_UiIZ-cPz1GtV5i1I2iOSOHuimiXBI0e-Oe_u6X3oVAbCiAZOTEBtTXw4tsluTITPqA8zMsfxIKMjiqNQ"; // get from https://dashboard.web3auth.io

const chainConfig = {
chainId: "0x1",
displayName: "Ethereum Mainnet",
chainNamespace: CHAIN_NAMESPACES.EIP155,
tickerName: "Ethereum",
ticker: "ETH",
decimals: 18,
rpcTarget: "https://rpc.ankr.com/eth",
blockExplorerUrl: "https://etherscan.io",
};

// Initialising Web3Auth Single Factor Auth SDK
const web3authSfa = new Web3Auth({
clientId, // Get your Client ID from Web3Auth Dashboard
web3AuthNetwork: "sapphire_mainnet", // Get your Network from Web3Auth Dashboard
usePnPKey: false, // Setting this to true returns the same key as PnP Web SDK, By default, this SDK returns CoreKitKey.
});

// Initializing Ethereum Provider
const privateKeyProvider = new EthereumPrivateKeyProvider({
config: { chainConfig },
});

Here, we're using the chainConfig property to set the chainId and chainNamespace among other parameters. The chainId and chainNamespace are the id and the namespace respectively of the chain you're connecting to. We've initialized them for EVM for this guide. You can find the list of available providers here to select from.

Additionally, sometimes you might face clogging in the network because the test network is a bit clogged at that point. To avoid this, we can use the property rpcTarget and pass over the URL of the node you want to connect to.

Initializing the Web3Auth SDK

web3authSfa.init(privateKeyProvider);

Authentication

Getting the idToken and initializing Web3Auth

const signInWithEmailPasswordless = async (): Promise<any> => {
setIsLoading(true);
try {
await sendSignInLinkToEmail(auth, email, {
url: window.location.href,
handleCodeInApp: true,
});
setIsLoading(false);
} catch (error) {
setIsLoading(false);
console.log(error);
}
};

Here, we're using the sendSignInLinkToEmail function from the Firebase SDK to send the sign-in link to the user's email.

Initialising Web3Auth
useEffect(() => {
if (isSignInWithEmailLink(auth, window.location.href)) {
const email = localStorage.getItem("email_for_web3auth_sfa_demo") || "hello@web3auth.io";
signInWithEmailLink(auth, email, window.location.href)
.then(async (loginRes) => {
const idToken = await loginRes.user.getIdToken(true);

await web3authSfa.connect({
verifier: "w3a-firebase-demo",
verifierId: loginRes.user.uid,
idToken: idToken,
});
})
.catch((error) => {
console.log(error);
});
}
}, []);

Please refer to our example if you need help with handling the session with React.

info

Since we are directly using Single Factor Auth SDK to log in, the Web3Auth getUserInfo function won't work. We need to get the user details directly from the idToken.

Get the User Profile

import { safeatob } from "@toruslabs/openlogin-utils";

const parseToken = (token: any) => {
try {
const token = token.split(".")[1]; // payload
return JSON.parse(safeatob(token));
} catch (err) {
console.error(err);
return null;
}
};

const userProfile = parseToken(idToken);

Logout

Logging out your user is as simple as calling the logout function on the Web3Auth SDK.

auth
.signOut()
.then(() => {
console.log("successfully logged out");
})
.catch((err) => {
console.log(err);
});
await web3authSfa.logout();

Interacting with the Blockchain

So if you have completed this far, it means that you have successfully authenticated your user. Now, you can use the provider returned by Web3Auth as web3auth.provider to interact with your blockchain. You can use the Provider SDKs to perform RPC Calls to your blockchain.

Web3Auth is chain agnostic, ie. depending on whatever blockchain or layer-2 you use, Web3Auth can easily support that. Web3Auth has native providers for EVM and Solana blockchains and for others, you can get the private key in the user scope and make RPC calls. For standardising the type of provider, Web3Auth Base provides a IProvider from which you can create your own provider.

  • Ethereum Provider gives you the capability of making RPC calls to the EVM compatible blockchains.
  • Solana Provider gives you the capability of making RPC calls to the Solana blockchain.
  • XRPL Provider gives you the capability of making RPC calls to the XRPL blockchain.
  • If you want to use any other chain except Solana or EVM chains, for ex: Starknet, you can specify the value of chainNamespace field as other in the Web3Auth SDK Constructor. Refer to: Using other blockchains

Get User Accounts

const getAccounts = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const web3 = new Web3(provider as any);
const userAccounts = await web3.eth.getAccounts();
console.log(userAccounts);
};

View User Balance

const getBalance = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const web3 = new Web3(provider as any);
const accounts = await web3.eth.getAccounts();
const balance = await web3.eth.getBalance(accounts[0]);
console.log(web3.utils.fromWei(balance));
};

Sign Message

const signMessage = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const web3 = new Web3(provider as any);
// Get user's Ethereum public address
const account = (await web3.eth.getAccounts())[0];

// Message
const message = "Hello MPC, Bye Bye SeedPhrase";

const typedMessage = [
{
type: "string",
name: "message",
value: message,
},
];
const params = [JSON.stringify(typedMessage), account];
const method = "eth_signTypedData";

const signedMessage = await this.provider.request({
method,
params,
});
console.log(signedMessage);
};

Sign Transaction

const signTransaction = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const web3 = new Web3(provider as any);
const accounts = await web3.eth.getAccounts();

const txRes = await web3.eth.signTransaction({
from: accounts[0],
to: accounts[0],
value: web3.utils.toWei("0.0001"),
chainId: 1, // change it to your specific chain id.
});
console.log(txRes.transactionHash);
};

Send Transaction

const sendTransaction = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const web3 = new Web3(provider as any);
const accounts = await web3.eth.getAccounts();

const txRes = await web3.eth.sendTransaction({
from: accounts[0],
to: accounts[0],
value: web3.utils.toWei("0.0001"),
chainId: 1, // change it to your specific chain id.
});
console.log(txRes.transactionHash);
};

Example Code

The code for the example can be found here.

Questions?

Ask us on Web3Auth Community Portal.