---
description: Integrate Firebase Authentication into a Capacitor app, from the Firebase project through Google and email sign-in, native config, and troubleshooting.
title: Firebase Authentication in Capacitor: Setup & Best Practices - Capawesome
image: https://capawesome.io/docs/assets/images/social/blog/capacitor-firebase-authentication-guide.png
---

<!doctype html> 

[Skip to content ](#firebase-authentication-in-capacitor-setup-best-practices) 

[📲 Introducing **Build Sharing** — get your builds onto testers' devices with a link & QR code. No account required. ](/blog/share-mobile-app-builds-with-testers/) 

* [ SDKs ](/docs/sdks/)
* [ Formbricks ](/docs/sdks/capacitor/formbricks/)
* [ Geocoder ](/docs/sdks/capacitor/geocoder/)
* [ Google Sign-In ](/docs/sdks/capacitor/google-sign-in/)
* [ Grafana Faro ](/docs/sdks/capacitor/grafana-faro/)
* [ Gyroscope ](/docs/sdks/capacitor/gyroscope/)
* [ Haptics ](/docs/sdks/capacitor/haptics/)
* [ Home Indicator ](/docs/sdks/capacitor/home-indicator/)
* [ In-App Browser ](/docs/sdks/capacitor/in-app-browser/)
* [ Install Referrer ](/docs/sdks/capacitor/install-referrer/)
* [ Intercom ](/docs/sdks/capacitor/intercom/)
* [ Intune ](/docs/sdks/capacitor/intune/)
* [ Keep Awake ](/docs/sdks/capacitor/keep-awake/)
* [ libSQL ](/docs/sdks/capacitor/libsql/)
* [ Light Sensor ](/docs/sdks/capacitor/light-sensor/)
* [ Live Update ](/docs/sdks/capacitor/live-update/)
* [ Localization ](/docs/sdks/capacitor/localization/)
* [ Mail Composer ](/docs/sdks/capacitor/mail-composer/)
* [ Managed Configurations ](/docs/sdks/capacitor/managed-configurations/)
* [ Maps Launcher ](/docs/sdks/capacitor/maps-launcher/)
* [ Media Session ](/docs/sdks/capacitor/media-session/)
* [ ML Kit ](/docs/sdks/capacitor/mlkit/)
* [ Navigation Bar ](/docs/sdks/capacitor/navigation-bar/)
* [ Network ](/docs/sdks/capacitor/network/)
* [ NFC ](/docs/sdks/capacitor/nfc/)
* [ Node.js ](/docs/sdks/capacitor/nodejs/)
* [ OAuth ](/docs/sdks/capacitor/oauth/)
* [ Passkeys ](/docs/sdks/capacitor/passkeys/)
* [ Password Autofill ](/docs/sdks/capacitor/password-autofill/)
* [ PDF Generator ](/docs/sdks/capacitor/pdf-generator/)
* [ PDF Viewer ](/docs/sdks/capacitor/pdf-viewer/)
* [ Pedometer ](/docs/sdks/capacitor/pedometer/)
* [ Permissions ](/docs/sdks/capacitor/permissions/)
* [ Phone Dialer ](/docs/sdks/capacitor/phone-dialer/)
* [ Photo Editor ](/docs/sdks/capacitor/photo-editor/)
* [ Photo Manipulator ](/docs/sdks/capacitor/photo-manipulator/)
* [ PixLive ](/docs/sdks/capacitor/pixlive/)
* [ PostHog ](/docs/sdks/capacitor/posthog/)
* [ Printer ](/docs/sdks/capacitor/printer/)
* [ Privacy Screen ](/docs/sdks/capacitor/privacy-screen/)
* [ Proximity Sensor ](/docs/sdks/capacitor/proximity-sensor/)
* [ Purchases ](/docs/sdks/capacitor/purchases/)
* [ RealtimeKit ](/docs/sdks/capacitor/realtimekit/)
* [ Root Detection ](/docs/sdks/capacitor/root-detection/)
* [ Screen Brightness ](/docs/sdks/capacitor/screen-brightness/)
* [ Screen Orientation ](/docs/sdks/capacitor/screen-orientation/)
* [ Screen Reader ](/docs/sdks/capacitor/screen-reader/)
* [ Screenshot ](/docs/sdks/capacitor/screenshot/)
* [ Secure Preferences ](/docs/sdks/capacitor/secure-preferences/)
* [ Settings Launcher ](/docs/sdks/capacitor/settings-launcher/)
* [ Shake ](/docs/sdks/capacitor/shake/)
* [ Silent Mode ](/docs/sdks/capacitor/silent-mode/)
* [ SIM ](/docs/sdks/capacitor/sim/)
* [ SMS Composer ](/docs/sdks/capacitor/sms-composer/)
* [ Speech Recognition ](/docs/sdks/capacitor/speech-recognition/)
* [ Speech Synthesis ](/docs/sdks/capacitor/speech-synthesis/)
* [ Share Target ](/docs/sdks/capacitor/share-target/)
* [ Square Mobile Payments ](/docs/sdks/capacitor/square-mobile-payments/)
* [ SQLite ](/docs/sdks/capacitor/sqlite/)
* [ Superwall ](/docs/sdks/capacitor/superwall/)
* [ System WebView ](/docs/sdks/capacitor/system-webview/)
* [ Tauri ](/docs/sdks/capacitor/tauri/)
* [ Text Interaction ](/docs/sdks/capacitor/text-interaction/)
* [ Text Zoom ](/docs/sdks/capacitor/text-zoom/)
* [ Thermal State ](/docs/sdks/capacitor/thermal-state/)
* [ Toast ](/docs/sdks/capacitor/toast/)
* [ Torch ](/docs/sdks/capacitor/torch/)
* [ Vault ](/docs/sdks/capacitor/vault/)
* [ Volume ](/docs/sdks/capacitor/volume/)
* [ Wallet ](/docs/sdks/capacitor/wallet/)
* [ Wifi ](/docs/sdks/capacitor/wifi/)
* [ YouTube Player ](/docs/sdks/capacitor/youtube-player/)
* [ Zip ](/docs/sdks/capacitor/zip/)
* [ Cordova ](/docs/sdks/cordova/)
* [ Cloud ](/docs/cloud/)
* [ Integrations ](/docs/cloud/live-updates/integrations/)
* Concepts
* Reference
* [ Troubleshooting ](/docs/cloud/live-updates/troubleshooting/)
* [ FAQ ](/docs/cloud/live-updates/faq/)
* [ Native Builds ](/docs/cloud/native-builds/)
* [ Set Up Environments ](/docs/cloud/native-builds/environments/)
* [ Overwrite Native Configurations ](/docs/cloud/native-builds/native-configurations/)
* [ Auto-Increment Build Numbers ](/docs/cloud/native-builds/auto-incrementing-build-numbers/)
* [ Configure the Web Build Script ](/docs/cloud/native-builds/web-build-script/)
* [ Build from a Monorepo ](/docs/cloud/native-builds/monorepo/)
* [ Use pnpm, Yarn, or bun ](/docs/cloud/native-builds/package-managers/)
* [ Install Private npm Packages ](/docs/cloud/native-builds/npm-private-registry/)
* [ Override the Java Version ](/docs/cloud/native-builds/override-java-version/)
* [ Custom iOS Provisioning Profiles ](/docs/cloud/native-builds/custom-ios-provisioning-profiles/)
* [ Build without Git ](/docs/cloud/native-builds/build-without-git/)
* [ Access Git Behind a Firewall ](/docs/cloud/native-builds/firewall-access/)
* [ Integrations ](/docs/cloud/native-builds/integrations/)
* Reference
* [ Troubleshooting ](/docs/cloud/native-builds/troubleshooting/)
* [ FAQ ](/docs/cloud/native-builds/faq/)
* [ App Store Publishing ](/docs/cloud/app-store-publishing/)
* [ Submit a Build ](/docs/cloud/app-store-publishing/submit-a-build/)
* [ Submit Automatically After a Build ](/docs/cloud/app-store-publishing/submit-automatically/)
* [ Troubleshooting ](/docs/cloud/app-store-publishing/troubleshooting/)
* [ FAQ ](/docs/cloud/app-store-publishing/faq/)
* [ Automations ](/docs/cloud/automations/)
* [ Reference ](/docs/cloud/automations/reference/)
* [ Troubleshooting ](/docs/cloud/automations/troubleshooting/)
* [ FAQ ](/docs/cloud/automations/faq/)
* [ Assist ](/docs/cloud/assist/)
* [ CLI ](/docs/cloud/cli/)
* APIs and SDKs
* [ Webhooks ](/docs/cloud/webhooks/)
* [ Integrations ](/docs/cloud/integrations/)
* Notifications
* Account
* [ Organization ](/docs/cloud/organizations/)
* [ Two-Factor Enforcement ](/docs/cloud/organizations/two-factor-authentication/)
* [ Audit Logs ](/docs/cloud/organizations/audit-logs/)
* [ Billing ](/docs/cloud/organizations/billing/)
* [ License Keys ](/docs/cloud/license-keys/)
* [ AI ](/docs/ai/)
* [ Insiders ](/docs/insiders/)
* [ Billing & Plans ](/docs/insiders/billing-and-plans/)
* [ FAQ ](/docs/insiders/faq/)
* [ License ](https://capawesome.io/legal/eula/)
* [ Support ](/docs/support/)
* [ Contributing ](/docs/contributing/)
* Contributing code
* [ Code of Conduct ](/docs/contributing/code-of-conduct/)
* [ Questions ](https://docs.github.com/en/discussions/collaborating-with-your-community-using-discussions/participating-in-a-discussion#creating-a-discussion)
* [ Blog ](/blog/)
* Categories

* [ Your Firebase Authentication Options ](#your-firebase-authentication-options)
* [ Before You Start ](#before-you-start)
* [ Step 1: Create a Firebase Project and Enable Sign-In ](#step-1-create-a-firebase-project-and-enable-sign-in)
* [ Step 2: Install the Plugin ](#step-2-install-the-plugin)
* [ Step 3: Add Firebase to Your Native Apps ](#step-3-add-firebase-to-your-native-apps)
* [ Step 4: Configure the Plugin ](#step-4-configure-the-plugin)
* [ Step 5: Set Up the Google Provider ](#step-5-set-up-the-google-provider)
* [ Implementing Sign-In ](#implementing-sign-in)
* [ Managing the User ](#managing-the-user)
* [ Run on a Device and Verify ](#run-on-a-device-and-verify)
* [ Auth State Persistence: What Happens Offline ](#auth-state-persistence-what-happens-offline)
* [ Firebase Authentication Best Practices ](#firebase-authentication-best-practices)
* [ Common Errors and Troubleshooting ](#common-errors-and-troubleshooting)
* [ FAQ ](#faq)
* [ Ship Auth Fixes Without Waiting on the App Store ](#ship-auth-fixes-without-waiting-on-the-app-store)
* [ Conclusion ](#conclusion)

* Related links

# Firebase Authentication in Capacitor: Setup & Best Practices[¶](#firebase-authentication-in-capacitor-setup-best-practices "Permanent link")

Most apps need to know who's using them, and building that from scratch (password hashing, session tokens, social login handshakes, phone verification) is a lot of surface area to get wrong. The [Capacitor Firebase Authentication plugin](/docs/sdks/capacitor/firebase/authentication/) wraps Firebase's native Android and iOS Authentication SDKs, plus the Firebase JS SDK on web, behind a single API, so you get production-grade sign-in without writing that layer yourself.

The catch is that the setup has real depth — a Firebase project, native config files, and per-provider steps that the reference docs assume you already understand. This guide walks the whole thing end to end: creating the project, installing and configuring the plugin, wiring up Google and email/password sign-in, and then the production practices and gotchas that actually trip teams up.

[ ![Build and deploy your Capacitor app with Capawesome Cloud](https://capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.png?t=1) ](/) 

## How to Integrate Firebase Authentication in a Capacitor App[¶](#how-to-integrate-firebase-authentication-in-a-capacitor-app "Permanent link")

Integrating Firebase Authentication into a Capacitor app comes down to six steps:

1. **Create a Firebase project** and enable the sign-in providers you want.
2. **Install** `@capacitor-firebase/authentication` and the `firebase` package.
3. **Add the native config files** (`google-services.json` on Android, `GoogleService-Info.plist` on iOS).
4. **Configure the plugin** — list your providers in `capacitor.config.ts` and add the URL handler to the iOS `AppDelegate`.
5. **Do the per-provider setup** (for Google: the Android SHA-1 fingerprint and the iOS reversed client ID).
6. **Call the sign-in method** — `signInWithGoogle()`, `signInWithEmailAndPassword()`, and so on — and track the result with the `authStateChange` listener.

The rest of this guide walks through each step in full, with the platform-specific configuration and troubleshooting a complete integration needs.

## What Is Firebase Authentication?[¶](#what-is-firebase-authentication "Permanent link")

[Firebase Authentication](https://firebase.google.com/docs/auth) is Google's managed identity service. It handles sign-up, sign-in, and session management so you don't have to run your own auth server. The [Capacitor Firebase Authentication plugin](/docs/sdks/capacitor/firebase/authentication/) exposes that service through native sign-in flows on Android and iOS (using Google's official platform SDKs under the hood) and the Firebase JS SDK on web, all behind one shared TypeScript API.

A working example can be found here: [capawesome-team/capacitor-firebase-authentication-demo](https://github.com/capawesome-team/capacitor-firebase-authentication-demo).

### Why Not Just Use the Firebase JS SDK?[¶](#why-not-just-use-the-firebase-js-sdk "Permanent link")

Signing users in with the Firebase JS SDK inside a Capacitor app means running OAuth flows (Google, Facebook, and similar providers) inside an embedded WebView, and Google has spent years [locking that pattern down](https://developers.googleblog.com/2016/08/modernizing-oauth-interactions-in-native-apps.html) rather than supporting it further. Social providers increasingly restrict or block sign-in attempts that come from inside an embedded WebView, so JS-SDK-only sign-in tends to get less reliable over time on native platforms, not more. This plugin avoids that entirely by using each platform's native SDK for native sign-in, which shows the same official system sign-in UI a fully native app would use.

The trade-off worth knowing: a native sign-in only authenticates your app's native layer. If you also need the user signed in on the web layer, for example to call another Firebase service through its own JS SDK, that requires an extra step, covered in the [plugin's Firebase JS SDK documentation](https://github.com/capawesome-team/capacitor-firebase/blob/main/packages/authentication/docs/firebase-js-sdk.md).

## Your Firebase Authentication Options[¶](#your-firebase-authentication-options "Permanent link")

Every sign-in method runs through the same plugin API, so "which option" is mostly a product decision, not a technical one. Here's the full menu and what each one needs on top of the base setup:

| Sign-in option                              | Platforms         | Extra native setup                        |
| ------------------------------------------- | ----------------- | ----------------------------------------- |
| Email & password                            | Android, iOS, Web | None                                      |
| Email link (passwordless)                   | Android, iOS, Web | Deep link handling                        |
| Google                                      | Android, iOS, Web | SHA-1 (Android), reversed client ID (iOS) |
| Apple                                       | Android, iOS, Web | "Sign in with Apple" capability           |
| Facebook, Microsoft, GitHub, Twitter, Yahoo | Android, iOS, Web | Per-provider (linked in the docs)         |
| Phone number (SMS)                          | Android, iOS      | Per-provider config                       |
| Play Games / Game Center                    | Android / iOS     | Per-provider config                       |
| Anonymous (guest)                           | Android, iOS, Web | None                                      |
| Custom token / OpenID Connect               | Android, iOS, Web | Your own backend or OIDC provider         |

If you're not sure where to start, **email/password and Google** cover the vast majority of apps, and they're the two this guide configures in full. Add **anonymous** sign-in when you want people to try the app before creating an account, and reach for **custom token** when you already have your own backend issuing identities.

## Before You Start[¶](#before-you-start "Permanent link")

This guide assumes you already have a Capacitor app with the `android` and/or `ios` platforms added, and a Google account to create a Firebase project with. Everything else — the project, the SDKs, the native config — we'll set up below.

The full walkthrough covers the two most common sign-in methods, **email/password** and **Google**, because together they exercise every part of the setup: the Firebase console, the native config files, plugin configuration, and (for Google) the platform-specific provider steps. Every other provider follows the same shape, and each one is linked in the [Installation](/docs/sdks/capacitor/firebase/authentication/#installation) section of the plugin docs.

## Step 1: Create a Firebase Project and Enable Sign-In[¶](#step-1-create-a-firebase-project-and-enable-sign-in "Permanent link")

1. Open the [Firebase console](https://console.firebase.google.com/) and create a new project (or reuse an existing one).
2. In the left sidebar, open **Build → Authentication** and click **Get started**.
3. Under the **Sign-in method** tab, enable the providers you want. For this guide, enable **Email/Password** and **Google**. Each provider you enable here has to match a provider you configure in the app later, or sign-in will fail.

That's the whole backend. Firebase now manages your user directory; the rest of the work is connecting your app to it.

## Step 2: Install the Plugin[¶](#step-2-install-the-plugin "Permanent link")

Install the plugin and the `firebase` package (the plugin uses it for the web layer and for account linking), then sync the native projects:

`[](#%5F%5Fcodelineno-0-1)npm install @capacitor-firebase/authentication firebase
[](#%5F%5Fcodelineno-0-2)npx cap sync
`

## Step 3: Add Firebase to Your Native Apps[¶](#step-3-add-firebase-to-your-native-apps "Permanent link")

The plugin talks to Firebase through the native config files Firebase generates for each platform. This is the step most setup problems trace back to, so it's worth doing carefully. The full reference is in the plugin's [Add Firebase to your project](https://github.com/capawesome-team/capacitor-firebase/blob/main/docs/firebase-setup.md) guide; the essentials:

**Android**

1. In the Firebase console, add an **Android** app and enter your app's package name — the `appId` from your `capacitor.config.ts`.
2. Download the generated `google-services.json` and place it in `android/app/google-services.json`.
3. Make sure the Google Services Gradle plugin is applied (the Capacitor Android template usually includes it) so the SDKs can read that file.

**iOS**

1. In the Firebase console, add an **iOS** app and enter your bundle ID (again, the `appId` from `capacitor.config.ts`).
2. Download `GoogleService-Info.plist` and move it to `ios/App/App/GoogleService-Info.plist`.
3. Open the project in Xcode and drag the file into the `App/App` group so it's registered in the project. When prompted, add it to all targets.

**Web**

Register a **Web** app in the console and initialize the Firebase JS SDK with the config snippet it gives you. You only need this if you're targeting the web platform.

## Step 4: Configure the Plugin[¶](#step-4-configure-the-plugin "Permanent link")

Tell the plugin which providers to load natively by listing them in `capacitor.config.ts`. On native platforms, only the providers listed here are initialized:

`[](#%5F%5Fcodelineno-1-1)/// <reference types="@capacitor-firebase/authentication" />
[](#%5F%5Fcodelineno-1-2)
[](#%5F%5Fcodelineno-1-3)import { CapacitorConfig } from '@capacitor/cli';
[](#%5F%5Fcodelineno-1-4)
[](#%5F%5Fcodelineno-1-5)const config: CapacitorConfig = {
[](#%5F%5Fcodelineno-1-6)  plugins: {
[](#%5F%5Fcodelineno-1-7)    FirebaseAuthentication: {
[](#%5F%5Fcodelineno-1-8)      skipNativeAuth: false,
[](#%5F%5Fcodelineno-1-9)      providers: ['google.com'],
[](#%5F%5Fcodelineno-1-10)    },
[](#%5F%5Fcodelineno-1-11)  },
[](#%5F%5Fcodelineno-1-12)};
[](#%5F%5Fcodelineno-1-13)
[](#%5F%5Fcodelineno-1-14)export default config;
`

Leave `skipNativeAuth` as `false` unless you specifically want the plugin to skip native sign-in and let you drive the Firebase JS SDK yourself — it changes how the whole plugin behaves, and it's a common source of confusion (more on that under [auth state](#auth-state-persistence-what-happens-offline) below). Email/password sign-in doesn't need a `providers` entry, so if you were only doing email/password you could leave the array empty.

On **iOS**, confirm your `AppDelegate.swift` includes the URL-handling function that lets native sign-in return to your app:

`[](#%5F%5Fcodelineno-2-1)func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
[](#%5F%5Fcodelineno-2-2)  return ApplicationDelegateProxy.shared.application(app, open: url, options: options)
[](#%5F%5Fcodelineno-2-3)}
`

## Step 5: Set Up the Google Provider[¶](#step-5-set-up-the-google-provider "Permanent link")

Email/password needs nothing beyond enabling it in Step 1 — no native configuration at all. Google is the more involved case, and it's representative of what any native social provider requires. The complete, always-current steps live in the [Google Sign-In setup doc](https://github.com/capawesome-team/capacitor-firebase/blob/main/packages/authentication/docs/setup-google.md); here's what they amount to.

**Android**

1. Add `google.com` to the `providers` array (Step 4).
2. Enable the native Google dependency in `android/variables.gradle`:

`[](#%5F%5Fcodelineno-3-1)ext {
[](#%5F%5Fcodelineno-3-2)    rgcfaIncludeGoogle = true
[](#%5F%5Fcodelineno-3-3)    androidxCredentialsVersion = '1.3.0'
[](#%5F%5Fcodelineno-3-4)}
`

Then run `npx cap update` to pull in the native dependencies. 3\. Add your app's **SHA-1 fingerprint** to the Firebase console (Project settings → your Android app). Without it, Google Sign-In will fail — and note that the Play Store re-signs your app with its own certificate, so you'll eventually need the SHA-1 from Play Console's **App signing** page too, not just your local debug keystore.

**iOS**

1. Add `google.com` to the `providers` array (Step 4).
2. If you use **Swift Package Manager**, the Google dependencies are already included — nothing to add. If you use **CocoaPods**, add the `CapacitorFirebaseAuthentication/Google` pod to your `Podfile` and run `npx cap update`.
3. Add a **custom URL scheme** for your reversed client ID: open your target's **Info → URL Types** in Xcode, add a URL scheme, and paste in the `REVERSED_CLIENT_ID` value from your `GoogleService-Info.plist`.

Apple Sign-In follows the same pattern with less work — add `apple.com` to `providers` and enable the **Sign in with Apple** capability in Xcode — and every other provider is documented the same way in the [Installation](/docs/sdks/capacitor/firebase/authentication/#installation) section.

## Implementing Sign-In[¶](#implementing-sign-in "Permanent link")

With the setup done, the actual sign-in calls are short. Every sign-in method resolves with the signed-in `user`.

### Email and Password[¶](#email-and-password "Permanent link")

Register a new account with [createUserWithEmailAndPassword(...)](/docs/sdks/capacitor/firebase/authentication/#createuserwithemailandpassword), and sign an existing user in with [signInWithEmailAndPassword(...)](/docs/sdks/capacitor/firebase/authentication/#signinwithemailandpassword):

`[](#%5F%5Fcodelineno-4-1)import { FirebaseAuthentication } from '@capacitor-firebase/authentication';
[](#%5F%5Fcodelineno-4-2)
[](#%5F%5Fcodelineno-4-3)const register = async (email: string, password: string) => {
[](#%5F%5Fcodelineno-4-4)  const result = await FirebaseAuthentication.createUserWithEmailAndPassword({
[](#%5F%5Fcodelineno-4-5)    email,
[](#%5F%5Fcodelineno-4-6)    password,
[](#%5F%5Fcodelineno-4-7)  });
[](#%5F%5Fcodelineno-4-8)  return result.user;
[](#%5F%5Fcodelineno-4-9)};
[](#%5F%5Fcodelineno-4-10)
[](#%5F%5Fcodelineno-4-11)const signIn = async (email: string, password: string) => {
[](#%5F%5Fcodelineno-4-12)  const result = await FirebaseAuthentication.signInWithEmailAndPassword({
[](#%5F%5Fcodelineno-4-13)    email,
[](#%5F%5Fcodelineno-4-14)    password,
[](#%5F%5Fcodelineno-4-15)  });
[](#%5F%5Fcodelineno-4-16)  return result.user;
[](#%5F%5Fcodelineno-4-17)};
`

### Google[¶](#google "Permanent link")

After the Step 5 setup, native Google sign-in is a single call to [signInWithGoogle(...)](/docs/sdks/capacitor/firebase/authentication/#signinwithgoogle) — it shows the system Google account picker and returns the signed-in user:

`[](#%5F%5Fcodelineno-5-1)import { FirebaseAuthentication } from '@capacitor-firebase/authentication';
[](#%5F%5Fcodelineno-5-2)
[](#%5F%5Fcodelineno-5-3)const signInWithGoogle = async () => {
[](#%5F%5Fcodelineno-5-4)  const result = await FirebaseAuthentication.signInWithGoogle();
[](#%5F%5Fcodelineno-5-5)  return result.user;
[](#%5F%5Fcodelineno-5-6)};
`

### Apple[¶](#apple "Permanent link")

Once you've added the **Sign in with Apple** capability (Step 5), Apple sign-in is the same single call to [signInWithApple(...)](/docs/sdks/capacitor/firebase/authentication/#signinwithapple):

`[](#%5F%5Fcodelineno-6-1)import { FirebaseAuthentication } from '@capacitor-firebase/authentication';
[](#%5F%5Fcodelineno-6-2)
[](#%5F%5Fcodelineno-6-3)const signInWithApple = async () => {
[](#%5F%5Fcodelineno-6-4)  const result = await FirebaseAuthentication.signInWithApple();
[](#%5F%5Fcodelineno-6-5)  return result.user;
[](#%5F%5Fcodelineno-6-6)};
`

Every other social provider follows the same one-call shape — `signInWithFacebook()`, `signInWithMicrosoft()`, `signInWithGithub()`, and so on — once that provider's setup is done.

### Other Options: Phone and Passwordless Email[¶](#other-options-phone-and-passwordless-email "Permanent link")

**Phone number** sign-in (Android and iOS only) sends an SMS code that you confirm with [confirmVerificationCode(...)](/docs/sdks/capacitor/firebase/authentication/#confirmverificationcode). The code arrives through the `phoneCodeSent` event:

`[](#%5F%5Fcodelineno-7-1)import { FirebaseAuthentication } from '@capacitor-firebase/authentication';
[](#%5F%5Fcodelineno-7-2)
[](#%5F%5Fcodelineno-7-3)const signInWithPhoneNumber = async (phoneNumber: string) => {
[](#%5F%5Fcodelineno-7-4)  await FirebaseAuthentication.addListener('phoneCodeSent', async event => {
[](#%5F%5Fcodelineno-7-5)    const verificationCode = window.prompt('Enter the code sent to your phone');
[](#%5F%5Fcodelineno-7-6)    await FirebaseAuthentication.confirmVerificationCode({
[](#%5F%5Fcodelineno-7-7)      verificationId: event.verificationId,
[](#%5F%5Fcodelineno-7-8)      verificationCode,
[](#%5F%5Fcodelineno-7-9)    });
[](#%5F%5Fcodelineno-7-10)  });
[](#%5F%5Fcodelineno-7-11)  await FirebaseAuthentication.signInWithPhoneNumber({ phoneNumber });
[](#%5F%5Fcodelineno-7-12)};
`

**Passwordless email** sends a sign-in link with [sendSignInLinkToEmail(...)](/docs/sdks/capacitor/firebase/authentication/#sendsigninlinktoemail) and completes when the user opens it with [signInWithEmailLink(...)](/docs/sdks/capacitor/firebase/authentication/#signinwithemaillink):

`[](#%5F%5Fcodelineno-8-1)import { FirebaseAuthentication } from '@capacitor-firebase/authentication';
[](#%5F%5Fcodelineno-8-2)
[](#%5F%5Fcodelineno-8-3)const sendSignInLink = async (email: string) => {
[](#%5F%5Fcodelineno-8-4)  await FirebaseAuthentication.sendSignInLinkToEmail({
[](#%5F%5Fcodelineno-8-5)    email,
[](#%5F%5Fcodelineno-8-6)    actionCodeSettings: {
[](#%5F%5Fcodelineno-8-7)      url: 'https://www.example.com/finishSignUp',
[](#%5F%5Fcodelineno-8-8)      handleCodeInApp: true,
[](#%5F%5Fcodelineno-8-9)    },
[](#%5F%5Fcodelineno-8-10)  });
[](#%5F%5Fcodelineno-8-11)  window.localStorage.setItem('emailForSignIn', email);
[](#%5F%5Fcodelineno-8-12)};
[](#%5F%5Fcodelineno-8-13)
[](#%5F%5Fcodelineno-8-14)const completeSignInLink = async () => {
[](#%5F%5Fcodelineno-8-15)  const email = window.localStorage.getItem('emailForSignIn') ?? '';
[](#%5F%5Fcodelineno-8-16)  const result = await FirebaseAuthentication.signInWithEmailLink({
[](#%5F%5Fcodelineno-8-17)    email,
[](#%5F%5Fcodelineno-8-18)    emailLink: window.location.href,
[](#%5F%5Fcodelineno-8-19)  });
[](#%5F%5Fcodelineno-8-20)  return result.user;
[](#%5F%5Fcodelineno-8-21)};
`

For your own backend, [signInWithCustomToken(...)](/docs/sdks/capacitor/firebase/authentication/#signinwithcustomtoken) and [signInWithOpenIdConnect(...)](/docs/sdks/capacitor/firebase/authentication/#signinwithopenidconnect) authenticate against a custom token or any OpenID Connect provider.

### Reacting to Sign-In State[¶](#reacting-to-sign-in-state "Permanent link")

Don't scatter `getCurrentUser()` calls through your UI. Listen for `authStateChange` once and let it drive your app's signed-in/signed-out state:

`[](#%5F%5Fcodelineno-9-1)import { FirebaseAuthentication } from '@capacitor-firebase/authentication';
[](#%5F%5Fcodelineno-9-2)
[](#%5F%5Fcodelineno-9-3)FirebaseAuthentication.addListener('authStateChange', change => {
[](#%5F%5Fcodelineno-9-4)  console.log('user', change.user);
[](#%5F%5Fcodelineno-9-5)});
`

**Attention:** this listener does not fire if you initialize the plugin with the `skipNativeAuth` configuration option. In that setup, use the Firebase JavaScript SDK's own `onAuthStateChanged` instead. This is a common source of "my auth listener never fires" reports, and it's almost always this option being enabled.

### Wiring the Listener Into Angular, React, or Vue[¶](#wiring-the-listener-into-angular-react-or-vue "Permanent link")

The sign-in calls are identical in any framework — what differs is where you register the `authStateChange` listener and how you clean it up. Angular is the one special case: plugin events fire outside its change-detection zone, so update state inside `NgZone.run(...)` or the UI won't refresh.

AngularReactVue

`[](#%5F%5Fcodelineno-10-1)import { Injectable, NgZone, signal } from '@angular/core';
[](#%5F%5Fcodelineno-10-2)import { FirebaseAuthentication, User } from '@capacitor-firebase/authentication';
[](#%5F%5Fcodelineno-10-3)
[](#%5F%5Fcodelineno-10-4)@Injectable({ providedIn: 'root' })
[](#%5F%5Fcodelineno-10-5)export class AuthService {
[](#%5F%5Fcodelineno-10-6)  readonly user = signal<User | null>(null);
[](#%5F%5Fcodelineno-10-7)
[](#%5F%5Fcodelineno-10-8)  constructor(private readonly zone: NgZone) {
[](#%5F%5Fcodelineno-10-9)    FirebaseAuthentication.addListener('authStateChange', change => {
[](#%5F%5Fcodelineno-10-10)      this.zone.run(() => this.user.set(change.user));
[](#%5F%5Fcodelineno-10-11)    });
[](#%5F%5Fcodelineno-10-12)  }
[](#%5F%5Fcodelineno-10-13)}
`

`[](#%5F%5Fcodelineno-11-1)import { useEffect, useState } from 'react';
[](#%5F%5Fcodelineno-11-2)import { FirebaseAuthentication, User } from '@capacitor-firebase/authentication';
[](#%5F%5Fcodelineno-11-3)
[](#%5F%5Fcodelineno-11-4)export const useAuthUser = () => {
[](#%5F%5Fcodelineno-11-5)  const [user, setUser] = useState<User | null>(null);
[](#%5F%5Fcodelineno-11-6)  useEffect(() => {
[](#%5F%5Fcodelineno-11-7)    const handle = FirebaseAuthentication.addListener('authStateChange', change =>
[](#%5F%5Fcodelineno-11-8)      setUser(change.user),
[](#%5F%5Fcodelineno-11-9)    );
[](#%5F%5Fcodelineno-11-10)    return () => {
[](#%5F%5Fcodelineno-11-11)      handle.then(listener => listener.remove());
[](#%5F%5Fcodelineno-11-12)    };
[](#%5F%5Fcodelineno-11-13)  }, []);
[](#%5F%5Fcodelineno-11-14)  return user;
[](#%5F%5Fcodelineno-11-15)};
`

`[](#%5F%5Fcodelineno-12-1)import { onMounted, onUnmounted, ref } from 'vue';
[](#%5F%5Fcodelineno-12-2)import { FirebaseAuthentication, User } from '@capacitor-firebase/authentication';
[](#%5F%5Fcodelineno-12-3)
[](#%5F%5Fcodelineno-12-4)export const useAuthUser = () => {
[](#%5F%5Fcodelineno-12-5)  const user = ref<User | null>(null);
[](#%5F%5Fcodelineno-12-6)  let remove: (() => void) | undefined;
[](#%5F%5Fcodelineno-12-7)  onMounted(async () => {
[](#%5F%5Fcodelineno-12-8)    const listener = await FirebaseAuthentication.addListener(
[](#%5F%5Fcodelineno-12-9)      'authStateChange',
[](#%5F%5Fcodelineno-12-10)      change => (user.value = change.user),
[](#%5F%5Fcodelineno-12-11)    );
[](#%5F%5Fcodelineno-12-12)    remove = () => listener.remove();
[](#%5F%5Fcodelineno-12-13)  });
[](#%5F%5Fcodelineno-12-14)  onUnmounted(() => remove?.());
[](#%5F%5Fcodelineno-12-15)  return user;
[](#%5F%5Fcodelineno-12-16)};
`

### Signing Out[¶](#signing-out "Permanent link")

`[](#%5F%5Fcodelineno-13-1)import { FirebaseAuthentication } from '@capacitor-firebase/authentication';
[](#%5F%5Fcodelineno-13-2)
[](#%5F%5Fcodelineno-13-3)const signOut = async () => {
[](#%5F%5Fcodelineno-13-4)  await FirebaseAuthentication.signOut();
[](#%5F%5Fcodelineno-13-5)};
`

## Managing the User[¶](#managing-the-user "Permanent link")

Beyond sign-in, the plugin exposes the operations a real account system needs.

### Authenticate Your Backend with an ID Token[¶](#authenticate-your-backend-with-an-id-token "Permanent link")

If your own backend needs to know who's calling it, fetch a fresh ID token with [getIdToken(...)](/docs/sdks/capacitor/firebase/authentication/#getidtoken) and send it with the request:

`[](#%5F%5Fcodelineno-14-1)import { FirebaseAuthentication } from '@capacitor-firebase/authentication';
[](#%5F%5Fcodelineno-14-2)
[](#%5F%5Fcodelineno-14-3)const getIdToken = async () => {
[](#%5F%5Fcodelineno-14-4)  const { user } = await FirebaseAuthentication.getCurrentUser();
[](#%5F%5Fcodelineno-14-5)  if (!user) {
[](#%5F%5Fcodelineno-14-6)    return;
[](#%5F%5Fcodelineno-14-7)  }
[](#%5F%5Fcodelineno-14-8)  const { token } = await FirebaseAuthentication.getIdToken();
[](#%5F%5Fcodelineno-14-9)  return token;
[](#%5F%5Fcodelineno-14-10)};
`

Your server then verifies that token before trusting it (covered under [best practices](#firebase-authentication-best-practices)).

### Email Verification and Password Reset[¶](#email-verification-and-password-reset "Permanent link")

If you support email/password, these aren't optional extras — users hit them on day one:

`[](#%5F%5Fcodelineno-15-1)import { FirebaseAuthentication } from '@capacitor-firebase/authentication';
[](#%5F%5Fcodelineno-15-2)
[](#%5F%5Fcodelineno-15-3)const verifyEmail = async () => {
[](#%5F%5Fcodelineno-15-4)  await FirebaseAuthentication.sendEmailVerification();
[](#%5F%5Fcodelineno-15-5)};
[](#%5F%5Fcodelineno-15-6)
[](#%5F%5Fcodelineno-15-7)const resetPassword = async (email: string) => {
[](#%5F%5Fcodelineno-15-8)  await FirebaseAuthentication.sendPasswordResetEmail({ email });
[](#%5F%5Fcodelineno-15-9)};
`

### Guest Access with Account Linking[¶](#guest-access-with-account-linking "Permanent link")

Let users try the app anonymously with [signInAnonymously(...)](/docs/sdks/capacitor/firebase/authentication/#signinanonymously), then upgrade them to a permanent account later with a `linkWithX` method so they keep whatever they did as a guest:

`[](#%5F%5Fcodelineno-16-1)import { FirebaseAuthentication } from '@capacitor-firebase/authentication';
[](#%5F%5Fcodelineno-16-2)
[](#%5F%5Fcodelineno-16-3)const continueAsGuest = async () => {
[](#%5F%5Fcodelineno-16-4)  const result = await FirebaseAuthentication.signInAnonymously();
[](#%5F%5Fcodelineno-16-5)  return result.user;
[](#%5F%5Fcodelineno-16-6)};
[](#%5F%5Fcodelineno-16-7)
[](#%5F%5Fcodelineno-16-8)const upgradeGuestWithGoogle = async () => {
[](#%5F%5Fcodelineno-16-9)  const result = await FirebaseAuthentication.linkWithGoogle();
[](#%5F%5Fcodelineno-16-10)  return result.user;
[](#%5F%5Fcodelineno-16-11)};
`

The user must already be signed in (anonymously or otherwise) on the native layer for linking to work; it's not a substitute for a fresh sign-in.

### Deleting the Account[¶](#deleting-the-account "Permanent link")

`[](#%5F%5Fcodelineno-17-1)import { FirebaseAuthentication } from '@capacitor-firebase/authentication';
[](#%5F%5Fcodelineno-17-2)
[](#%5F%5Fcodelineno-17-3)const deleteAccount = async () => {
[](#%5F%5Fcodelineno-17-4)  await FirebaseAuthentication.deleteUser();
[](#%5F%5Fcodelineno-17-5)};
`

## Run on a Device and Verify[¶](#run-on-a-device-and-verify "Permanent link")

Native sign-in only runs on a real device or emulator, not in the browser dev server, so build and launch the native app:

`[](#%5F%5Fcodelineno-18-1)npx cap sync
[](#%5F%5Fcodelineno-18-2)npx cap run android   # or: npx cap run ios
`

Trigger a sign-in from your UI, then confirm it worked from two directions:

* **In your app**, log the result of `getCurrentUser()` (or watch your `authStateChange` listener) and check that `user` is non-null with the expected `uid` and `email`.
* **In the Firebase console**, open **Authentication → Users** — the account you just signed in with should appear in the list.

If the user shows up in both places, your setup is wired correctly end to end.

## Auth State Persistence: What Happens Offline[¶](#auth-state-persistence-what-happens-offline "Permanent link")

On Android and iOS, the native Firebase SDKs cache the signed-in user locally, so [getCurrentUser()](/docs/sdks/capacitor/firebase/authentication/#getcurrentuser) resolves with the current session even with no network connection. You don't need to be online just to check whether someone is logged in. On web, you control this behavior explicitly with [setPersistence()](/docs/sdks/capacitor/firebase/authentication/#setpersistence), which is a web-only method for choosing between local storage, session-only, or no persistence at all.

## Firebase Authentication Best Practices[¶](#firebase-authentication-best-practices "Permanent link")

### Test Against the Firebase Emulator First[¶](#test-against-the-firebase-emulator-first "Permanent link")

Point the plugin at a local [Firebase Emulator](https://firebase.google.com/docs/emulator-suite) instance during development so you're not creating real users or burning SMS quota while iterating:

`[](#%5F%5Fcodelineno-19-1)import { FirebaseAuthentication } from '@capacitor-firebase/authentication';
[](#%5F%5Fcodelineno-19-2)
[](#%5F%5Fcodelineno-19-3)await FirebaseAuthentication.useEmulator({
[](#%5F%5Fcodelineno-19-4)  host: '10.0.2.2',
[](#%5F%5Fcodelineno-19-5)  port: 9099,
[](#%5F%5Fcodelineno-19-6)});
`

### Budget Time for the iOS App Tracking Transparency Prompt[¶](#budget-time-for-the-ios-app-tracking-transparency-prompt "Permanent link")

If you support Facebook Login, plan for Apple's App Tracking Transparency (ATT) requirement. The plugin exposes `checkAppTrackingTransparencyPermission()` and `requestAppTrackingTransparencyPermission()` specifically for this, and both are iOS-only. Skipping this step is a common cause of Facebook Login misbehaving or getting flagged in App Store review on iOS.

### Verify ID Tokens on Your Server, Don't Just Check They Exist[¶](#verify-id-tokens-on-your-server-dont-just-check-they-exist "Permanent link")

Retrieving an ID token client-side and forwarding it to your backend isn't enough on its own. Your server has to actually verify the token's signature and expiration before trusting it, otherwise you're just trusting whatever the client sends. Use the [Firebase Admin SDK](https://firebase.google.com/docs/auth/admin/verify-id-tokens) for this:

`[](#%5F%5Fcodelineno-20-1)import { getAuth } from 'firebase-admin/auth';
[](#%5F%5Fcodelineno-20-2)
[](#%5F%5Fcodelineno-20-3)const decodedToken = await getAuth().verifyIdToken(idToken);
[](#%5F%5Fcodelineno-20-4)const uid = decodedToken.uid;
`

A token that merely _exists_ tells you nothing. A token that _verifies_ tells you who the request actually came from.

### Handling "Account Already Exists with a Different Credential"[¶](#handling-account-already-exists-with-a-different-credential "Permanent link")

If a user tries to sign in with Google after already registering with email/password (or vice versa), Firebase throws rather than silently creating a second account for the same email. Historically, `fetchSignInMethodsForEmail()` let you look up which provider an email is already registered with, so you could redirect the user to the right sign-in method. **This no longer works reliably**: if [Email Enumeration Protection](https://cloud.google.com/identity-platform/docs/admin/email-enumeration-protection) is enabled on your project (the default for any Firebase project created on or after September 15, 2023), the method always returns an empty array, regardless of how many methods actually exist for that email. Don't build your account-linking UX around this method for a new project; instead, catch the specific sign-in error and prompt the user to sign in with their original method, then link the new provider with `linkWithX()`.

### Multi-Tenant Apps[¶](#multi-tenant-apps "Permanent link")

If you're building a B2B app where each customer needs isolated users (a common SaaS requirement), `setTenantId()` and `getTenantId()` scope authentication to a specific tenant within a [Google Cloud Identity Platform](https://cloud.google.com/identity-platform) project — a paid upgrade from vanilla Firebase Authentication, not a free-tier feature:

`[](#%5F%5Fcodelineno-21-1)import { FirebaseAuthentication } from '@capacitor-firebase/authentication';
[](#%5F%5Fcodelineno-21-2)
[](#%5F%5Fcodelineno-21-3)await FirebaseAuthentication.setTenantId({ tenantId: 'tenant-a' });
`

## Common Errors and Troubleshooting[¶](#common-errors-and-troubleshooting "Permanent link")

* **Google Sign-In fails instantly on Android (a `DEVELOPER_ERROR`, or the sheet closing right away).** Almost always a missing or mismatched SHA-1 fingerprint, or Google not enabled under **Sign-in method** in the console. Add your keystore's SHA-1 to the Firebase project — and the Play Store's own signing SHA-1 once you release.
* **Google Sign-In does nothing on iOS.** The reversed client ID URL scheme is missing. Add the `REVERSED_CLIENT_ID` value from `GoogleService-Info.plist` under **Info → URL Types** in Xcode (Step 5).
* **App crashes on launch, or Firebase reports it isn't configured.** The `google-services.json` / `GoogleService-Info.plist` file is missing, in the wrong folder, or (on iOS) wasn't added to the Xcode project. Re-check Step 3 and run `npx cap sync`.
* **`authStateChange` never fires.** `skipNativeAuth` is enabled. Turn it off, or switch to the Firebase JS SDK's `onAuthStateChanged`.
* **Sign-in returns to Safari or a blank screen on iOS instead of your app.** The `open url` function is missing from `AppDelegate.swift` (Step 4).
* **"An account already exists with the same email address."** The email is registered with a different provider. Catch the error, prompt the user to sign in with their original method, then link the new provider with `linkWithX()`.
* **The UI doesn't update after sign-in in Angular.** The `authStateChange` callback ran outside Angular's zone — wrap your state update in `NgZone.run(...)` (see the framework example above).

## FAQ[¶](#faq "Permanent link")

### Does Firebase Authentication work with Ionic?[¶](#does-firebase-authentication-work-with-ionic "Permanent link")

Yes. Ionic apps run on Capacitor, so there's nothing Ionic-specific to do: install `@capacitor-firebase/authentication`, follow the same setup steps above, and call the same sign-in methods from your Ionic pages. The [framework examples](#wiring-the-listener-into-angular-react-or-vue) apply as-is, since every Ionic app is built with Angular, React, or Vue.

### Do I still need to install the `firebase` npm package?[¶](#do-i-still-need-to-install-the-firebase-npm-package "Permanent link")

Yes. Even though sign-in runs through the native SDKs on Android and iOS, the plugin depends on the `firebase` package for the web platform and for account linking, so `npm install @capacitor-firebase/authentication firebase` installs both.

### Which providers need a SHA-1 fingerprint?[¶](#which-providers-need-a-sha-1-fingerprint "Permanent link")

Google Sign-In on Android is the one that reliably needs it. Add the SHA-1 from your local keystore during development, and remember to also add the SHA-1 from Play Console's **App signing** page once you publish — Google Play re-signs your app with a different certificate, which is why Google Sign-In often works in development but fails after release.

### Why is `displayName` null the second time a user signs in with Apple?[¶](#why-is-displayname-null-the-second-time-a-user-signs-in-with-apple "Permanent link")

Because Apple only sends the user's full name on their _first_ authorization for your app. It's a privacy decision on Apple's part, not a bug in the plugin. If you don't capture and store `displayName` on that first sign-in, it won't be included again on later sign-ins unless the user manually revokes your app's access in their Apple ID settings and re-authorizes.

### How is this different from Capawesome's own Sign-In and OAuth plugins?[¶](#how-is-this-different-from-capawesomes-own-sign-in-and-oauth-plugins "Permanent link")

The [Capacitor Google Sign-In](/blog/how-to-sign-in-with-google-using-capacitor/), [Apple Sign-In](/blog/how-to-sign-in-with-apple-using-capacitor/), and [OAuth](/blog/how-to-sign-in-with-auth0-using-capacitor/) plugins authenticate the user against Google, Apple, or a generic OAuth/OIDC provider directly and hand you the resulting credential; they don't require a Firebase project at all. The Capacitor Firebase Authentication plugin instead authenticates against **Firebase's own user system**, so the same login also creates a managed Firebase user you can look up, link providers to, and issue Firebase ID tokens for. Pick Firebase Authentication if you're already using other Firebase services (Firestore, Cloud Functions) and want one unified user identity across all of them; pick the standalone plugins if you just need the sign-in credential itself with no Firebase project involved.

### Is Firebase Authentication free to use?[¶](#is-firebase-authentication-free-to-use "Permanent link")

The core sign-in methods (email/password, social providers, anonymous, custom token) have no Firebase charge. Phone number sign-in bills for SMS messages once you exceed Firebase's free monthly quota, and features like multi-tenancy require upgrading to Google Cloud's Identity Platform, which has its own pricing. Check the current [Firebase pricing page](https://firebase.google.com/pricing) before committing to phone auth or multi-tenant support at scale.

## Ship Auth Fixes Without Waiting on the App Store[¶](#ship-auth-fixes-without-waiting-on-the-app-store "Permanent link")

Now that sign-in runs through the native SDKs, every change touches a native build — and auth is exactly the feature you want to fix fast when something breaks for real users. [Capawesome Cloud](https://capawesome.io/) is built for that side of the job: it builds your iOS and Android apps in the cloud (no local signing setup to wrestle with), and its live updates let you push fixes to your app's web layer — your sign-in screens and the code calling the plugin — straight to users, skipping the store review wait for those changes. When you do need a full native release, it can automate the App Store and Play Store submission too.

[Book a Capawesome Cloud Demo](https://cal.com/team/capawesome/cloud-demo)

## Conclusion[¶](#conclusion "Permanent link")

Firebase Authentication covers the sign-in methods most apps actually need (social, email, phone, anonymous, and custom backends) behind one API that works the same on Android, iOS, and web. The setup is where the real work is — a Firebase project, the native config files, and per-provider steps like Google's SHA-1 and reversed client ID — but once that's in place, the sign-in calls themselves are one line each. The parts that trip teams up in production are rarely the plugin: it's Apple only sending `displayName` once, Google Sign-In needing the Play Store's own SHA-1, the `skipNativeAuth` option silencing your auth listener, and treating an ID token as trustworthy just because it exists instead of verifying it server-side.

If you want to go deeper from here:

* [Capacitor Firestore: Real-Time Data & Offline Sync](/blog/capacitor-firebase-cloud-firestore-guide/) — pair Firebase Authentication with per-user data and security rules that check `request.auth`.
* [Capacitor Push Notifications: The Complete Guide](/blog/capacitor-push-notifications-guide/) — another Firebase-backed plugin, often added to the same app right after authentication.
* [How to Securely Store Credentials with Capacitor](/blog/how-to-securely-store-credentials-with-capacitor/) — for storing session tokens or other credentials after a successful sign-in.

Questions or something you ran into that isn't covered here? Drop into the [Capawesome Discord server](https://discord.gg/VCXxSVjefW) — and subscribe to the [Capawesome newsletter](https://capawesome.io/newsletter/) if you want the next deep-dive in your inbox.

July 29, 2026 

Back to top

```json
{
      "@context": "https://schema.org",
      "@type": "BlogPosting",
      "headline": "Firebase Authentication in Capacitor: Setup \u0026 Best Practices",
      "description": "Integrate Firebase Authentication into a Capacitor app, from the Firebase project through Google and email sign-in, native config, and troubleshooting.",
      "image": "https://capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.png",
      "datePublished": "2026-07-29T00:00:00+00:00",
      "dateModified": "2026-07-29T00:00:00+00:00",
      "author": [
        {
          "@type": "Person",
          "name": "Dayana Jabif",
          "url": "https://github.com/djabif"
        }
      ],
      "publisher": {
        "@type": "Organization",
        "name": "Capawesome",
        "url": "https://capawesome.io",
        "logo": {
          "@type": "ImageObject",
          "url": "https://capawesome.io/assets/images/logo.svg"
        }
      },
      "articleSection": "Capacitor",
      "keywords": ["Capacitor", "Firebase", "Guides", "SDKs"],
      "isPartOf": {
        "@type": "Blog",
        "@id": "https://capawesome.io/blog/#blog"
      },
      "mainEntityOfPage": "https://capawesome.io/blog/capacitor-firebase-authentication-guide/",
      "url": "https://capawesome.io/blog/capacitor-firebase-authentication-guide/"
    }
{
      "@context": "https://schema.org",
      "@type": "BreadcrumbList",
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "name": "Home",
          "item": "https://capawesome.io/"
        },
        {
          "@type": "ListItem",
          "position": 2,
          "name": "Blog",
          "item": "https://capawesome.io/blog/"
        },
        {
          "@type": "ListItem",
          "position": 3,
          "name": "Firebase Authentication in Capacitor: Setup \u0026 Best Practices",
          "item": "https://capawesome.io/blog/capacitor-firebase-authentication-guide/"
        }
      ]
    }
{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "What Is Firebase Authentication?", "acceptedAnswer": {"@type": "Answer", "text": "Firebase Authentication is Google's managed identity service. It handles sign-up, sign-in, and session management so you don't have to run your own auth server. The Capacitor Firebase Authentication plugin exposes that service through native sign-in flows on Android and iOS (using Google's official platform SDKs under the hood) and the Firebase JS SDK on web, all behind one shared TypeScript API. A working example can be found here: capawesome-team/capacitor-firebase-authentication-demo."}}, {"@type": "Question", "name": "Why Not Just Use the Firebase JS SDK?", "acceptedAnswer": {"@type": "Answer", "text": "Signing users in with the Firebase JS SDK inside a Capacitor app means running OAuth flows (Google, Facebook, and similar providers) inside an embedded WebView, and Google has spent years locking that pattern down rather than supporting it further. Social providers increasingly restrict or block sign-in attempts that come from inside an embedded WebView, so JS-SDK-only sign-in tends to get less reliable over time on native platforms, not more. This plugin avoids that entirely by using each platform's native SDK for native sign-in, which shows the same official system sign-in UI a fully native app would use. The trade-off worth knowing: a native sign-in only authenticates your app's native layer. If you also need the user signed in on the web layer, for example to call another Firebase service through its own JS SDK, that requires an extra step, covered in the plugin's Firebase JS SDK documentation."}}, {"@type": "Question", "name": "Does Firebase Authentication work with Ionic?", "acceptedAnswer": {"@type": "Answer", "text": "Yes. Ionic apps run on Capacitor, so there's nothing Ionic-specific to do: install @capacitor-firebase/authentication, follow the same setup steps above, and call the same sign-in methods from your Ionic pages. The framework examples apply as-is, since every Ionic app is built with Angular, React, or Vue."}}, {"@type": "Question", "name": "Do I still need to install the firebase npm package?", "acceptedAnswer": {"@type": "Answer", "text": "Yes. Even though sign-in runs through the native SDKs on Android and iOS, the plugin depends on the firebase package for the web platform and for account linking, so npm install @capacitor-firebase/authentication firebase installs both."}}, {"@type": "Question", "name": "Which providers need a SHA-1 fingerprint?", "acceptedAnswer": {"@type": "Answer", "text": "Google Sign-In on Android is the one that reliably needs it. Add the SHA-1 from your local keystore during development, and remember to also add the SHA-1 from Play Console's App signing page once you publish — Google Play re-signs your app with a different certificate, which is why Google Sign-In often works in development but fails after release."}}, {"@type": "Question", "name": "Why is displayName null the second time a user signs in with Apple?", "acceptedAnswer": {"@type": "Answer", "text": "Because Apple only sends the user's full name on their first authorization for your app. It's a privacy decision on Apple's part, not a bug in the plugin. If you don't capture and store displayName on that first sign-in, it won't be included again on later sign-ins unless the user manually revokes your app's access in their Apple ID settings and re-authorizes."}}, {"@type": "Question", "name": "How is this different from Capawesome's own Sign-In and OAuth plugins?", "acceptedAnswer": {"@type": "Answer", "text": "The Capacitor Google Sign-In, Apple Sign-In, and OAuth plugins authenticate the user against Google, Apple, or a generic OAuth/OIDC provider directly and hand you the resulting credential; they don't require a Firebase project at all. The Capacitor Firebase Authentication plugin instead authenticates against Firebase's own user system, so the same login also creates a managed Firebase user you can look up, link providers to, and issue Firebase ID tokens for. Pick Firebase Authentication if you're already using other Firebase services (Firestore, Cloud Functions) and want one unified user identity across all of them; pick the standalone plugins if you just need the sign-in credential itself with no Firebase project involved."}}, {"@type": "Question", "name": "Is Firebase Authentication free to use?", "acceptedAnswer": {"@type": "Answer", "text": "The core sign-in methods (email/password, social providers, anonymous, custom token) have no Firebase charge. Phone number sign-in bills for SMS messages once you exceed Firebase's free monthly quota, and features like multi-tenancy require upgrading to Google Cloud's Identity Platform, which has its own pricing. Check the current Firebase pricing page before committing to phone auth or multi-tenant support at scale."}}], "url": "https://capawesome.io/blog/capacitor-firebase-authentication-guide/"}
```
