FireLogGet the app

Firebase with React, React Native, Vue, Angular and Svelte

The Firebase SDK is the same everywhere. What changes is how you hold it — and React Native is the one that genuinely differs.

10 min read · updated August 5, 2026

Firebase publishes one JavaScript SDK. React, Vue, Angular and Svelte all use that same package, so most of what you learn transfers between them.

React Native is the exception, and the difference matters enough to cover first.

React Native needs a different package

You can install the standard firebase package in a React Native app. It will work for Firestore and Authentication. It will not give you push notifications, Crashlytics or Analytics.

Those three need native code — Objective-C on iOS, Java on Android. A JavaScript package cannot provide them.

`firebase` (JS SDK)`@react-native-firebase/*`
Firestore, AuthWorksWorks
Cloud MessagingNoYes
CrashlyticsNoYes
AnalyticsLimitedYes
Setupnpm install and goNative config files, pod install, rebuild
npm install @react-native-firebase/app
npm install @react-native-firebase/auth
npm install @react-native-firebase/messaging

cd ios && pod install   # iOS needs the native pods

Expo complicates this further. @react-native-firebase needs native modules, so it requires a development build rather than Expo Go. The JS SDK works in Expo Go, with the same limitations as above.

React

Initialise once, in its own module, and import from there. Calling initializeApp twice throws.

// firebase.js — the only place initializeApp is called
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
import { getFirestore } from "firebase/firestore";

const app = initializeApp({
  apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
  authDomain: "your-project.firebaseapp.com",
  projectId: "your-project",
});

export const auth = getAuth(app);
export const db = getFirestore(app);

The mistake that costs money is subscribing inside a component without cleaning up:

import { useEffect, useState } from "react";
import { collection, query, limit, onSnapshot } from "firebase/firestore";
import { db } from "./firebase";

function Orders() {
  const [orders, setOrders] = useState([]);

  useEffect(() => {
    const q = query(collection(db, "orders"), limit(20));

    const unsubscribe = onSnapshot(q, (snap) => {
      setOrders(snap.docs.map((d) => ({ id: d.id, ...d.data() })));
    });

    // Without this, every mount adds a listener and none are removed.
    return unsubscribe;
  }, []);

  return <ul>{orders.map((o) => <li key={o.id}>{o.total}</li>)}</ul>;
}

Two details are doing the work: returning unsubscribe so the listener is removed, and limit(20) so the query is bounded. Miss either and reads climb quietly.

Vue

The plain SDK works. VueFire wraps it in composables that tie Firebase data to Vue's reactivity, so documents update the view automatically and unsubscribe when the component unmounts.

import { useCollection } from "vuefire";
import { collection, query, limit } from "firebase/firestore";

const orders = useCollection(
  query(collection(db, "orders"), limit(20)),
);
// `orders` is reactive, and cleanup is handled for you.

Angular

AngularFire is the official wrapper. It exposes Firebase through Angular's dependency injection and returns Observables, which fits the rest of an Angular app.

import { Firestore, collectionData, collection } from "@angular/fire/firestore";

export class OrdersComponent {
  orders$ = collectionData(collection(this.firestore, "orders"));

  constructor(private firestore: Firestore) {}
}

With the async pipe in the template, subscription and cleanup are both handled for you.

Svelte

No official wrapper, and none is really needed. Svelte stores map onto Firebase listeners almost exactly — a custom store that subscribes on creation and unsubscribes on teardown is about fifteen lines.

The mistake every framework shares

Putting Firebase config in your JavaScript feels wrong. People hide the API key in environment variables and assume that secures it.

It does not, and it does not need to. The Firebase API key is not a secret. It identifies your project; it does not grant access. Anyone can read it out of your bundle, and that is by design.

What actually protects your data is security rules. If your rules are open, hiding the key changes nothing — an attacker reads it from the network tab in ten seconds. If your rules are correct, publishing the key costs you nothing.

Choosing

  1. React Native app? @react-native-firebase, from the start.
  2. React web app? The plain SDK, in one module, with cleanup in every effect.
  3. Vue? VueFire, for the reactivity binding.
  4. Angular? AngularFire, for the DI and Observables.
  5. Svelte or anything else? The plain SDK and a small store wrapper.

Frequently asked questions

What is the difference between firebase and @react-native-firebase?
The `firebase` JavaScript SDK covers Firestore and Authentication in React Native but cannot provide push notifications, Crashlytics or full Analytics, because those need native code. `@react-native-firebase` wraps the native SDKs and supports all of it.
Can I use Firebase with Expo?
Yes. The JavaScript SDK works in Expo Go with the usual limitations. `@react-native-firebase` needs native modules, so it requires a development build rather than Expo Go.
Is it safe to expose the Firebase API key in frontend code?
Yes. The key identifies your project rather than granting access, and it is designed to be public. Your security rules control access. Hiding the key adds nothing; correct rules are what matter.
Do I need AngularFire or VueFire?
No, the plain SDK works everywhere. The wrappers handle subscription and cleanup in a way that matches each framework's reactivity, which removes a common source of leaked listeners.
Why does my React app read Firestore so many times?
Usually a listener created inside a component that re-renders, without returning the unsubscribe function, or a query without a `limit()`. Each re-render adds another subscription and none are cleaned up.
Can I call initializeApp more than once?
No, it throws. Initialise Firebase in one module, export the services from it, and import them everywhere else.

Keep reading