Skip to main content

Integrating Firebase with Web3Auth PnP Android SDK

plug and playandroidkotlinfirebasecustom jwtid tokenevmWeb3Auth Team | January 17, 2023

This guide will cover the basics of how to use the Web3Auth Android SDK in your Android application with Firebase.

Demo APK: Download

Repository: https://github.com/Web3Auth/web3auth-pnp-examples/tree/main/android/android-firebase-example

Live Demo

Quick Start

npx degit Web3Auth/web3auth-pnp-examples/android/android-firebase-example w3a-android-firebase-demo
# Open in Android Studio

How it works?

When integrating Web3Auth Android SDK with Social Login the flow looks something like this:

Web3Auth - Firebase Login Flow

  • When a user logs in with Firebase, Firebase sends a JWT id_token to the app. This JWT token is sent to the Web3Auth SDK's login function.

  • Finally, on successful validation of the JWT token, Web3Auth SDK will generate a private key for the user, in a self-custodial way, resulting in easy onboarding for your user to the application.

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

  • Android API version 21 or newer.
  • A Firebase account to be used as Federated Identity Provider.

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

Setup

Setup your Firebase Project

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 Sign-in method tab, select any provider you wish to enanle. For the purpose of 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 Android

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

    Firebase Project Android - Set up web 1

  • In the next screen, enter the Android package name and click on Register app button to register the app for Android.

    Firebase Project Android - Set up web 2 Firebase Project Android - Set up web 3

  • In the Next screen, Download and add config file to your Android Studio Project as shown below. Then Click on Next button.

    Firebase Project Android - Set up web 4

  • Next screen shows ways to add Firebase to your application. To make the google-services.json config values accessible to Firebase SDKs, you need the Google services Gradle plugin. We will be adding the buildscript dependency to the <project>/build.gradle file.

    Firebase Project Android - Set up web 5

  • Then, in your module (app-level) build.gradle file, add both the google-services plugin and any Firebase SDKs that you want to use in your app:

    Firebase Project Android - Set up web 6

  • After adding the plugin and the desired SDKs, sync your Android project with Gradle files.

    Firebase Project Android - Set up web 7

Setup your Web3Auth Dashboard

  • 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 Android 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 Mainet, 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

  • Add {YOUR_APP_PACKAGE_NAME}://auth in the Whitelist URL field of the Web3Auth Dashboard.

Create Firebase Verifier on Web3Auth Dashboard

  • Create a Verifier from the Custom Auth Section of the Web3Auth Developer Dashboard with following configuration:

    • Choose a name of your choice for the verifier identifier. eg. w3a-firebase-verifier
    • Select environment: testnet, mainnet,aqua, or cyan as per your requirement.
    • Select Custom from the Login Provider.
    • Select Sub for the JWT Verifier ID.
    • Enter https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com as the JWK endpoint for Firebase's idToken.
    • JWT validation fields:
      • iss: https://securetoken.google.com/<firebase-project-id>.
      • aud: <firebase-project-id>
    • Click on Create button to create your verifier. It may take up to 10 minutes to deploy verifier on testnet. You'll receive an email once it's complete.

    Custom Authentication - Create Firebase Verifier

  • You will require the verifierName of the newly created verifier and clientId of the Plug and Play Project.

Using the Web3Auth SDK

To use the Web3Auth SDK, you'll need to add the dependency of the respective platform SDK of Web3Auth to your project. To know more about the available SDKs, please have a look at our SDK page.

For this guide, we will be using the Web3Auth Android SDK.

Add Web3Auth to Gradle

In your project-level gradle file add JitPack repository.

dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { url "https://jitpack.io" } // <-- Add this line
}
}

Then, in your app-level build.gradle dependencies section, add the following:

dependencies {
// ...
implementation 'com.github.web3auth:web3auth-android-sdk:9.0.1'
}

Permissions

Open your app's AndroidManifest.xml file and add the following permission. Please make sure the <uses-permission> element should be a direct child of the <manifest> root element.

<uses-permission android:name="android.permission.INTERNET" />

Configuration

Configure a Plug n Play project

  • Go to Web3Auth Developer Dashboard, and create or open an existing Web3Auth project.
  • Whitelist {SCHEME}://{YOUR_APP_PACKAGE_NAME} in the developer dashboard. This step is mandatory for the redirect to work.

Configure AndroidManifest File

Make sure your Main activity launchMode is set to singleTop in your AndroidManifest.xml

<activity
android:launchMode="singleTop"
android:name=".YourActivity">
// ...
</activity>

From version 7.1.2, please make sure to set android:allowBackup to false, and add tools:replace="android:fullBackupContent" in your AndroidManifest.xml file.

<application
android:allowBackup="false"
tools:replace="android:fullBackupContent"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher">
</application>

Open your app's AndroidManifest.xml file and add the following deep link intent filter to your Main activity

<intent-filter>
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data android:scheme="{scheme}" android:host="{YOUR_APP_PACKAGE_NAME}"/>
<!-- Accept URIs: w3a://com.example.w3aflutter -->
</intent-filter>

Initialization

Initialization is a two-step process:

  1. Creating a Web3Auth Instance
  2. Setting a Result URL

Please note that these are the most critical steps where you must pass on different parameters according to the preference of your project. Additionally, You must configure Whitelabeling and Custom Authentication within this step if you wish to customize your Web3Auth Instance.

Create Web3Auth Instance

In your activity, create a Web3Auth instance with your Web3Auth project's configurations.

web3Auth = Web3Auth(
Web3AuthOptions(
context = this,
clientId = getString(R.string.web3auth_project_id), // pass over your Web3Auth Client ID from Developer Dashboard
network = Network.MAINNET, // pass over the network you want to use (MAINNET, TESTNET, CYAN, AQUA )
redirectUrl = Uri.parse("{YOUR_APP_PACKAGE_NAME}://auth"), // your app's redirect URL
loginConfig = hashMapOf("jwt" to LoginConfigItem(
verifier = "web3auth-firebase-examples",
typeOfLogin = TypeOfLogin.JWT,
name = "Firebase Login",
clientId = getString(R.string.web3auth_project_id)
)
)
)
)

// Handle user signing in when app is not alive
web3Auth.setResultUrl(intent?.data)

Add the below line to your app/res/values/strings.xml file and paste your Web3Auth Client ID:

<resources>
<!-- ... -->
<string name="web3auth_project_id">CLIENT_ID_FROM_WEB3AUTH_DASHBOARD</string>
<!-- ... -->
</resources>

Read more about initializing the Android SDK here.

Set Result URL

Whenever user initiates a login flow, a new intent of CustomTabs is launched. It’s necessary step to use setResultUrl in onNewIntent method to successful track the login process.

override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)

// Handle user signing in when app is active
web3Auth.setResultUrl(intent.data)
}

Authentication

Logging in

Once initialized, you can use the web3Auth.login(LoginParams("{selectedLoginProvider}")) function to authenticate the user when they click the login button.

private fun signIn() {
// Initialize Firebase Auth
auth = Firebase.auth
auth.signInWithEmailAndPassword("android@firebase.com", "Android@Web3Auth")
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
// Sign in success, update UI with the signed-in user's information
Log.d(TAG, "signInWithEmail:success")
val user = auth.currentUser
user!!.getIdToken(true).addOnSuccessListener { result ->
val idToken = result.token

Log.d(TAG, "GetTokenResult result = $idToken")
val selectedLoginProvider = Provider.JWT
val loginCompletableFuture: CompletableFuture<Web3AuthResponse> = web3Auth.login(LoginParams(selectedLoginProvider, extraLoginOptions = ExtraLoginOptions(domain = "firebase", id_token = idToken)))

loginCompletableFuture.whenComplete { loginResponse, error ->
if (error == null) {
println(loginResponse)
reRender(loginResponse)
} else {
Log.d("MainActivity_Web3Auth", error.message ?: "Something went wrong" )
}
}
}
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "signInWithEmail:failure", task.exception)
Toast.makeText(baseContext, "Authentication failed.",
Toast.LENGTH_SHORT).show()

}
}
}

When connecting, the login function takes the LoginParams arguments for the login. See the LoginParams for more details.

Sample loginResponse

{
"privKey": "0ajjsdsd....",
"userInfo": {
"email": "w3a-heroes@web3auth.com",
"name": "Web3Auth Heroes",
"profileImage": "https://lh3.googleusercontent.com/a/Ajjjsdsmdjmnm...",
"verifier": "torus",
"verifierId": "w3a-heroes@web3auth.com",
"typeOfLogin": "google",
"aggregateVerifier": "w3a-google-sapphire",
"dappShare": "", // 24 words of seed phrase will be sent only incase of custom verifiers
"idToken": "<jwtToken issued by Web3Auth>",
"oAuthIdToken": "<jwtToken issued by OAuth Provider>", // will be sent only incase of custom verifiers
"oAuthAccessToken": "<accessToken issued by OAuth Provider>", // will be sent only incase of custom verifiers
"isMfaEnabled": false // Returns whether the user has enabled MFA or not
},
"ed25519PrivKey": "666523652352635....",
"coreKitKey": "0xajjsdsd....",
"coreKitEd25519PrivKey": "666523652352635....",
"sessionId": "0xajjsdsd...."
}

Get the User Profile

// Assuming the user is logged in, get the user profile from the web3AuthResponse
val userInfo = web3AuthResponse.userInfo

Using the web3Auth.login function, you can get the details of the logged in user. Please note that these details are not stored anywhere in Web3Auth network.

If you wish you add Multi Factor Authentication, use dApp Share

Logout

Logging out your user is as simple as calling the logout method. This method will clear the session data and the user will be logged out from Web3Auth.

val logoutCompletableFuture = web3Auth.logout()

Interacting with the Blockchain

Blockchain calls

Checkout the full codes to interact with the ETH Blockchain.

Get Account

// checkout the Connect Blockchain > Ethereum > Android to get full code.
private fun getAddress(): String {
println("Address:, ${credentials.address}")
return credentials.address
}

// Setup UI and event handlers
val getBalanceButton = findViewById<Button>(R.id.getBalanceButton)
getBalanceButton.setOnClickListener { getAddress() }

Get Balance

// checkout the Connect Blockchain > Ethereum > Android to get full code.
private fun getBalance(): BigInteger? {
val publicAddress = credentials.address
val ethBalance: EthGetBalance = web3.ethGetBalance(publicAddress, DefaultBlockParameterName.LATEST).sendAsync().get()
println("Balance: ${ethBalance.balance}")
return ethBalance.balance
}

// Setup UI and event handlers
val getBalanceButton = findViewById<Button>(R.id.getBalanceButton)
getBalanceButton.setOnClickListener { getBalance() }

Send Transaction

// checkout the Connect Blockchain > Ethereum > Android to get full code.
private fun sendTransaction(amount: Double, recipientAddress: String): String? {
val ethGetTransactionCount: EthGetTransactionCount = web3.ethGetTransactionCount(credentials.address, DefaultBlockParameterName.LATEST).sendAsync().get()
val nonce: BigInteger = ethGetTransactionCount.transactionCount
val value: BigInteger = Convert.toWei(amount.toString(), Convert.Unit.ETHER).toBigInteger()
val gasLimit: BigInteger = BigInteger.valueOf(21000)
val chainId: EthChainId = web3.ethChainId().sendAsync().get()

// Raw Transaction
val rawTransaction: RawTransaction = RawTransaction.createTransaction(
chainId.chainId.toLong(),
nonce,
gasLimit,
recipientAddress,
value,
"",
BigInteger.valueOf(5000000000),
BigInteger.valueOf(6000000000000)
)

val signedMessage: ByteArray = TransactionEncoder.signMessage(rawTransaction, credentials)
val hexValue: String = Numeric.toHexString(signedMessage)
val ethSendTransaction: EthSendTransaction = web3.ethSendRawTransaction(hexValue).sendAsync().get()
return if(ethSendTransaction.error != null) {
println("Tx Error: ${ethSendTransaction.error.message}")
ethSendTransaction.error.message
} else {
println("Tx Hash: ${ethSendTransaction.transactionHash}")
ethSendTransaction.transactionHash
}
}

// Setup UI and event handlers
val sendTransactionButton = findViewById<Button>(R.id.sendTransactionButton)
sendTransactionButton.setOnClickListener { sendTransaction() }

Example code

The code for the application we developed in this guide can be found in the Web3Auth Android Firebase Example. Check it out and try running it locally yourself!

Also, checkout other examples:

Questions?

Ask us on Web3Auth's Community Support Portal