#flutter#firebase#flutterfire#tutorial

Flutter Firebase: Setup, Auth, Firestore & FCM (2026)

A current Flutter Firebase guide: FlutterFire setup, authentication, Cloud Firestore, and push notifications (FCM) — with code and the common gotchas.

Navin Sharma 6 min read
Flutter Firebase: Setup, Auth, Firestore & FCM (2026)

Flutter Firebase — connecting a Flutter app to Google’s Firebase backend through the FlutterFire plugins — is the fastest way to ship a mobile app with authentication, a realtime database, push notifications, and analytics without building a backend yourself. FlutterFire is maintained by Google, so the SDKs track Firebase closely and the offline support is genuinely good. This is the current, end-to-end setup as of 2026: project configuration, auth, Cloud Firestore, and FCM, with working Dart and the errors that actually slow teams down.

We’ve shipped Flutter apps on Firebase since the FlutterFire plugins were young, so the gotchas below are from real builds, not the happy-path docs.

FlutterFire The plugin suite Google-maintained Firebase SDK for Flutter
flutterfire CLI Setup tool Generates firebase_options.dart for you
iOS + Android Platforms + web & desktop on most plugins
50k/day Firestore free reads Spark plan, before you pay

What FlutterFire actually is

FlutterFire is the official set of Flutter plugins that wrap Firebase’s native iOS and Android SDKs — firebase_core, firebase_auth, cloud_firestore, firebase_messaging, and a dozen more. The important word is native: these aren’t a thin wrapper over the Firebase JavaScript SDK, they bind to the platform SDKs, so you get native performance and the real offline cache rather than a bridged approximation. Google maintains them in lockstep with Firebase, which is why the Flutter integration stays more current than most third-party backend plugins. The practical upshot for you: a Flutter Firebase app gets production-grade auth, a syncing database, and push notifications with very little backend code — and the same plugins target web and desktop too if you ever expand beyond mobile.

Flutter Firebase setup

The modern setup path is the flutterfire CLI — it registers your apps and generates a firebase_options.dart file so you don’t hand-edit native config. Install the core plugin and the CLI, then configure:

flutter pub add firebase_core
dart pub global activate flutterfire_cli
flutterfire configure        # pick your Firebase project + platforms

Then initialize Firebase before runApp:

import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  runApp(const MyApp());
}

firebase_core is the required base plugin — every feature (firebase_auth, cloud_firestore, firebase_messaging) depends on it, so add it first. The flutterfire configure step is the part that’s improved most: it used to be manual google-services.json / GoogleService-Info.plist placement, and the CLI now handles registration for you. On iOS you still run pod install after adding plugins.

Flutter Firebase authentication

firebase_auth covers email/password, phone-OTP, and the social providers. The core pattern is email/password plus an auth-state stream that drives your navigation:

import 'package:firebase_auth/firebase_auth.dart';

final auth = FirebaseAuth.instance;
await auth.createUserWithEmailAndPassword(email: email, password: password);

auth.authStateChanges().listen((User? user) {
  // null = signed out; non-null = signed in. Gate your router here.
});

authStateChanges() is the piece that shapes app architecture — wrap your root with a StreamBuilder on it and switch between the authenticated and unauthenticated navigation stacks. For India-market apps (most of ours), Firebase phone-OTP auth is the path of least resistance and the most-used flow we ship; it needs the SHA-1/SHA-256 fingerprints registered on Android and APNs configured on iOS, which is the fiddly part — budget an afternoon for phone auth specifically. If you offer any social login on iOS, Apple Sign-In is mandatory per App Store review.

Flutter Firebase Firestore

cloud_firestore is the document database, and its realtime streams pair naturally with Flutter’s StreamBuilder:

import 'package:cloud_firestore/cloud_firestore.dart';

final db = FirebaseFirestore.instance;
await db.collection('orders').add({'item': 'Pizza', 'status': 'new'});

StreamBuilder(
  stream: db.collection('orders').snapshots(),
  builder: (context, snapshot) { /* rebuilds live on change */ },
);

The .snapshots() stream is Firestore’s standout feature — the UI re-renders the instant data changes, and the offline cache means the app keeps working without a connection and syncs on reconnect. The same caveat applies as everywhere with Firestore: it’s a document store, so relational queries (joins, aggregates) are painful and you denormalize. And reads are billed per document, so a screen that re-reads a whole collection on every open is how the bill surprises you — paginate with .limit() and .startAfterDocument(). If your data is genuinely relational, that’s the moment to weigh a SQL backend, which is exactly the trade-off in our supabase vs firebase comparison.

Flutter Firebase push notifications (FCM)

firebase_messaging handles Cloud Messaging. The flow: request permission, get the device token, send it to your backend, and handle foreground + background messages.

import 'package:firebase_messaging/firebase_messaging.dart';

final fm = FirebaseMessaging.instance;
await fm.requestPermission();
final token = await fm.getToken();   // register this server-side

FirebaseMessaging.onMessage.listen((msg) {
  // foreground message
});
FirebaseMessaging.onBackgroundMessage(_bgHandler); // top-level function!

Two things bite every team. First, the background handler (onBackgroundMessage) must be a top-level or static function, registered before runApp — not a closure inside a widget, or background messages silently fail. Second, iOS push is a wrapper over APNs, so without an APNs auth key uploaded to Firebase and the Push Notifications capability enabled in Xcode, nothing arrives on iPhones — and you can’t test push on the iOS simulator, you need a real device. Roughly four out of five “FCM doesn’t work on iOS” reports we see are the missing APNs key.

Common Flutter Firebase errors (and fixes)

A short list accounts for most lost time:

  • Version-solver conflicts. FlutterFire plugins must move together (see the callout above). Upgrade as a set; flutter clean; rebuild.
  • “No Firebase App ‘[DEFAULT]’ has been created.” You called a Firebase API before Firebase.initializeApp() finished. Make main async and await the init before runApp.
  • iOS build fails after adding a plugin. Run cd ios && pod install. New native modules aren’t linked until pods install — this catches people who only flutter pub add.
  • minSdkVersion too low on Android. Firebase Auth and others need minSdkVersion 21+ (23 for some). Bump it in android/app/build.gradle.
  • Web needs the config script. If you target Flutter web, the generated options handle it, but a stale index.html from an old setup can conflict — regenerate with flutterfire configure.

In our experience, the majority of “Flutter Firebase is broken” issues are configuration and version drift, not application logic. Get the setup disciplined and the SDK itself rarely fights you.

Securing your Firestore data

A working read/write isn’t a finished feature — without rules, your Firestore is open to anyone with your app’s config (which ships inside every install, so treat it as public). Firebase Security Rules are a separate rules language you write in firestore.rules or the console, and they’re where most Firebase data leaks originate, because teams ship the default test-mode rules (open until a fixed date 30 days out) and forget. The minimum for user-owned data: deny by default, then allow a user to read and write only documents where a uid field equals request.auth.uid. Test rules with the Firebase Local Emulator Suite before you ship — it runs locally and lets you assert “user A cannot read user B’s orders” as a real test, not a hope. This is a 30-minute step that prevents a headline, and it’s the single most-skipped part of the Flutter Firebase projects we audit.

Beyond auth and Firestore: the rest of FlutterFire

Most guides stop at auth + Firestore + push, but FlutterFire wraps the whole platform, and three more plugins earn their place in a production app. firebase_analytics is free and unlimited, logs screen views and custom events automatically, and feeds the funnels plus a BigQuery export if you need the raw data — wire it on day one, because retrofitting event tracking later means you lose months of baseline. firebase_crashlytics is the one we treat as non-negotiable: native crash reporting with full stack traces, free, surfacing the 1–2% of devices that produce most of your crashes; without it you’re debugging from one-star reviews. firebase_remote_config lets you change values — feature flags, copy, thresholds — without an app-store release, which matters when Apple review takes 1–3 days and you need to dark-launch or kill a feature fast.

Two more worth knowing: firebase_storage for user uploads (profile photos, documents) with the same security-rules model as Firestore, and cloud_functions to call server-side logic you don’t want on the client (payment confirmation, sending notifications, anything with a secret key). A typical production Flutter app uses six or seven FlutterFire plugins together — which is exactly why keeping them on the same version (the callout above) matters so much.

Flutter Firebase vs Supabase — quick call

Firebase isn’t the only Flutter backend, and the honest decision comes down to your data shape.

Flutter + Firebase FlutterFire ✓ pick
Flutter + Supabase supabase_flutter
Offline-first mobile
Excellent cache
Needs extra work
Phone-OTP + FCM
First-party, easy
Workable
Relational data / SQL
Painful (NoSQL)
Native Postgres
Pricing predictability
Per-read, can spike
Flat compute
Firebase for offline-first, push-heavy consumer apps on a deadline; Supabase for relational data + predictable cost.

For an offline-first or push-heavy Flutter app shipping fast, FlutterFire is the shortest path and we reach for it without hesitation. For relational, dashboard-style, or cost-sensitive apps, we weigh Supabase — the full comparison is in supabase vs firebase, and the wider field in our firebase alternatives guide. Building in React Native instead? See react native firebase.

When to bring in a team

A Flutter Firebase MVP — auth, a few Firestore collections, push — is a couple of weeks for a capable Flutter dev. The cost lives at the native edges: phone-OTP across both platforms, background push, offline-sync edge cases, and the periodic FlutterFire upgrade that touches native code. Those are where a “two-week MVP” can quietly become two months. A useful rule from the projects we inherit: scope about 60% of the timeline for the app and 40% for the platform edges — auth, push, store submission, and native upgrades. Teams that budget only the 60% are the ones whose app stays “almost done” for a quarter.

We build production Flutter apps on Firebase (and Supabase) and take over stalled ones — that’s the core of our Flutter development services. If you’d rather start from a working base than wire all this yourself, several of our readymade products already ship on a Flutter + Firebase stack.

Found this useful?

We build the apps described in this guide. Readymade or custom — ship in weeks.

Talk to our team →
Ready to ship?

We build the apps in this guide.

Readymade delivery apps from $1,500 or fully custom from brief. First commit within a week.

Reply time
< 4 hours
NDA on request
Signed same day
First commit
Within a week