You are building a web or mobile app and you need to handle authentication. Questions pile up: should I build a custom login system? Use a third-party provider? How do I manage sessions, tokens, and security?
We at Meteora Web have seen too many projects where authentication was hacked together: passwords stored in plaintext, handcrafted JWT tokens without refresh, social login using outdated libraries. The result? Vulnerabilities, lost users, and wasted debugging hours.
Firebase Authentication solves all this cleanly. Email/password, social login (Google, Facebook, Apple, GitHub), and phone number via SMS. You don't need to write a single login endpoint. No server-side session management. And security is handled by Google.
In this guide we'll show you how to integrate Firebase Authentication in a web app (JavaScript) and mobile (React Native / Flutter) with real, copy-paste-ready code for each provider. No abstract theory: only code we use in our own projects.
Why Firebase Authentication over a custom system
Building authentication from scratch is easy at the start: a user table, password hashing, a login endpoint. But complexity explodes when you need password resets, brute force protection, OAuth2 for social logins, verification emails, 2FA, refresh tokens, and scaling to millions of users without slowdowns.
Firebase does all this natively. We have used it for years across many projects because:
- No auth server to manage — you can still add custom logic with Cloud Functions if needed.
- Native support for all major social providers via a lightweight SDK.
- Seamless integration with Firestore, Storage, and Cloud Functions — the authenticated user is automatically synced.
- Security Rules ready to control access to your data.
If your project will only have a few dozen users, a custom system might be fine. But if you plan to scale, Firebase Authentication is the way to go.
Sponsored Protocol
Setting up Firebase Authentication step by step
1. Enable providers in the Firebase Console
Before writing code, activate the providers in your project. Go to Firebase Console → Authentication → Sign-in method. Here you'll find:
- Email/Password: enable and choose whether to allow password sign-up or only magic links.
- Google: enable and configure the client ID (Firebase generates it automatically for Web).
- Facebook: you need a Facebook Developer app with App ID and App Secret.
- Apple: mandatory for iOS apps that support social login (Apple guidelines). Works on Web with redirect.
- Phone: enable SMS authentication. Requires a billing account (each SMS costs), but you can use test numbers from the console during development.
2. Install and initialize the Firebase SDK
In your web project, install the package:
npm install firebase
Then initialize in your main file (e.g., firebase.js):
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
const firebaseConfig = {
apiKey: "...",
authDomain: "...",
projectId: "...",
storageBucket: "...",
messagingSenderId: "...",
appId: "..."
};
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
Note: the apiKey is public in the client, but that's fine. Security is enforced by Firebase Security Rules and authentication. Never place secrets in the frontend.
Login with email and password
The classic approach. Here's how to register and log in with email/password.
Sponsored Protocol
Registration
import { createUserWithEmailAndPassword } from "firebase/auth";
import { auth } from "./firebase.js";
async function signUp(email, password) {
try {
const userCredential = await createUserWithEmailAndPassword(auth, email, password);
console.log("User registered:", userCredential.user);
} catch (error) {
console.error("Error:", error.code, error.message);
}
}
Login
import { signInWithEmailAndPassword } from "firebase/auth";
async function signIn(email, password) {
try {
const userCredential = await signInWithEmailAndPassword(auth, email, password);
console.log("Login successful:", userCredential.user);
} catch (error) {
console.error("Error:", error.code, error.message);
}
}
Firebase automatically handles token refresh. No extra work needed. You can also use sendPasswordResetEmail for password reset. All methods are documented on Firebase Auth Web docs.
Login with Google
The most common social login. The Firebase SDK handles the entire OAuth2 flow. On Web you can use popup or redirect. We recommend popup for a smoother experience.
import { GoogleAuthProvider, signInWithPopup } from "firebase/auth";
const provider = new GoogleAuthProvider();
async function signInWithGoogle() {
try {
const result = await signInWithPopup(auth, provider);
const credential = GoogleAuthProvider.credentialFromResult(result);
console.log("Google user:", result.user);
// The access token is in credential.accessToken if you need it
} catch (error) {
console.error("Google login error:", error.code);
}
}
For mobile (React Native / Flutter), use the @react-native-firebase/auth or firebase_auth package.
Sponsored Protocol
Login with Facebook
Similar to Google, Facebook has its own provider.
import { FacebookAuthProvider, signInWithPopup } from "firebase/auth";
const provider = new FacebookAuthProvider();
async function signInWithFacebook() {
try {
const result = await signInWithPopup(auth, provider);
console.log("Facebook user:", result.user);
} catch (error) {
console.error("Facebook login error:", error.code);
}
}
First, enable the provider in the Firebase Console and paste your Facebook app credentials.
Login with Apple (Sign in with Apple)
Apple is required if you publish an app on the App Store that uses social login. On Web it works via redirect or popup.
import { OAuthProvider, signInWithPopup } from "firebase/auth";
const provider = new OAuthProvider("apple.com");
async function signInWithApple() {
try {
const result = await signInWithPopup(auth, provider);
console.log("Apple user:", result.user);
} catch (error) {
console.error("Apple login error:", error.code);
}
}
For iOS, use signInWithRedirect and handle the redirect properly.
Phone number authentication (SMS)
The user enters a phone number, Firebase sends an SMS with a one-time password (OTP). Great for mobile apps or 2FA.
Setup
In the Firebase Console, enable Phone. Then in code:
import { RecaptchaVerifier, signInWithPhoneNumber } from "firebase/auth";
async function sendSMS(phoneNumber) {
// Create an invisible or visible reCAPTCHA
window.recaptchaVerifier = new RecaptchaVerifier(auth, "recaptcha-container", {
size: "invisible", // or "normal" for visible
});
try {
const confirmationResult = await signInWithPhoneNumber(auth, phoneNumber, window.recaptchaVerifier);
window.confirmationResult = confirmationResult;
console.log("SMS sent");
} catch (error) {
console.error("Error sending SMS:", error);
}
}
async function verifyCode(code) {
try {
const result = await window.confirmationResult.confirm(code);
console.log("User verified:", result.user);
} catch (error) {
console.error("Wrong code:", error);
}
}
Note: Phone Auth on Web requires HTTPS (or localhost for development). reCAPTCHA is mandatory to prevent abuse.
Sponsored Protocol
Handling authentication state
Once a user signs in, you need to know if they are authenticated and react to state changes.
import { onAuthStateChanged } from "firebase/auth";
onAuthStateChanged(auth, (user) => {
if (user) {
console.log("User logged in:", user.uid);
// Update UI, load data
} else {
console.log("No user");
// Show login screen
}
});
This is an observable: it fires every time the state changes (login, logout, token refresh). Use it in your main app component.
Common pitfalls and how to avoid them
1. Provider not enabled
Before testing, make sure you enabled the provider in the Firebase Console. You'll get auth/operation-not-allowed error.
2. reCAPTCHA not configured for Phone Auth
Forgetting the reCAPTCHA will block SMS sending. Ensure you have a <div id="recaptcha-container"></div> in your DOM.
3. Incorrect Facebook credentials
Facebook requires a valid app with OAuth domain configured. Add your domain in the Facebook Developer Console.
Sponsored Protocol
4. Token management
Firebase automatically refreshes the ID token every hour. You don't need to implement manual refresh. But if you need to pass the token to your backend, use user.getIdToken().
Integration with a custom backend
Sometimes you have a backend that needs to verify the user's identity. Instead of duplicating the user database, use Firebase's ID token. Your backend verifies it with the Firebase Admin SDK.
// Backend (Node.js with Firebase Admin SDK)
import admin from "firebase-admin";
admin.initializeApp();
app.post("/api/data", async (req, res) => {
const token = req.headers.authorization?.split("Bearer ")[1];
try {
const decodedToken = await admin.auth().verifyIdToken(token);
const uid = decodedToken.uid;
// Now you can use uid to authorize access
} catch (error) {
res.status(401).send("Invalid token");
}
});
In summary — what to do now
- Go to the Firebase Console, create a project, and enable the providers you need (email, Google, Facebook, Apple, Phone).
- Install the Firebase SDK in your web or mobile project.
- Copy the initialization code and integrate the login methods for each provider.
- Use
onAuthStateChangedto manage routing and UI based on authentication state. - If you have a backend, set up Firebase Admin SDK and verify ID tokens.
Firebase Authentication eliminates the most tedious and risky part of user management. We use it in every project that requires login, and it has scaled to hundreds of thousands of users smoothly. For a deeper dive into the entire Firebase ecosystem, check out our definitive pillar guide on Firebase.