Skip to main content

Migration Guide


This page is archived and might not reflect the latest version of the FlutterFire plugins.

We changed the way developers integrate Flutter applications with Firebase in mid 2020. If you're currently using FlutterFire and wish to upgrade to the latest recommended versions, follow this guide to help ease that process.

If you're starting a fresh project, you can ignore this page and follow the Getting Started documentation.

The table below shows the recommended package versions for each plugin this migration guide covers.


Breaking Changes & Deprecations#

Although breaking changes have been kept to a minimum, the substantial changes and improvements which have been made required us to break a few things (for the greater good). Where possible, we've deprecated some "old ways" of integrating FlutterFire, and you should aim to replace these deprecations as soon as possible.

Migration Steps#

1. Adding firebase_core#

The FlutterFire plugins now depend on the firebase_core plugin. The plugin is responsible for connecting your Flutter application to your Firebase project(s), and without it all other plugins will not work.

Add the plugin to your pubspec.yaml file within your project:

sdk: flutter
firebase_core: "^0.7.0"

2. Update Firebase Plugins#

Update the Firebase plugins you use in your project to versions that are compatible with the new firebase_core plugin.

Edit the plugin versions in your pubspec.yaml file within your project to match the versions below:

sdk: flutter
firebase_core: "^0.7.0"
# Newly reworked plugins covered by this migration guide:
firebase_auth: "^0.20.1"
firebase_crashlytics: "^0.4.0"
cloud_firestore: "^0.16.0"
cloud_functions: "^0.9.0"
firebase_storage: "^7.0.0"
firebase_messaging: "^8.0.0-dev.15"
firebase_remote_config: "^0.8.0-dev.0"
# Updated to work with new core only plugins (no new changes):
firebase_admob: "^"
firebase_analytics: "^7.0.1"
firebase_database: "^6.0.0"
firebase_dynamic_links: "^0.7.0"
firebase_in_app_messaging: "^0.4.0+1"
firebase_performance: "^0.6.0+1"

Install the updated plugins by running the following command from the project root:

$ flutter pub get

We also recommend running flutter clean before continuing.

3. Platform Setup#

Even though you may have already set up your platform to connect with Firebase, we recommend following the new documentation steps for each platform to ensure everything is up-to-date.

Previously, it was possible to use FlutterFire without a "default" Firebase application. This has now changed, and all platforms now require an underlying default Firebase app to be registered. The platform specific guides below show you how to set up a default Firebase application:

A. Android Installation#

  • Ensure that the plugin is up-to-date.

    • Update the version by changing the classpath '' line in your android/build.gradle file to use version 4.3.3 or higher.
  • Ensure your apps Gradle wrapper distribution version is v5 or higher, FlutterFire uses v5.6.2 for its examples.

    • Update the version by changing the distributionUrl value in your projects android/gradle/wrapper/ file.
      • e.g. setting to v5.6.2: distributionUrl=https\://
  • Ensure that you're not manually importing any Firebase Android SDK dependencies in your android/app/build.gradle files dependencies { ... } section.

    • e.g. remove any lines similar to: implementation '{PRODUCT}:{VERSION}
    • The reworked plugins now automatically manage the versions of the Firebase SDKs used internally, so these are no longer required.
  • Crashlytics only: Remove the maven { url '' } line from your projects android/build.gradle file.

  • Crashlytics only: Remove the classpath '' line from your projects android/build.gradle file.

  • Crashlytics only: Remove the apply plugin: 'io.fabric' line from your projects android/app/build.gradle file.

  • Crashlytics only: Remove any dependencies referencing ** line from your projects android/app/build.gradle file (inside the dependencies { .. } block).

  • Crashlytics only: Follow the new Android integration steps shown in the FlutterFire Crashlytics installation documentation .

  • Messaging only: Remove any dependencies referencing ** line from your projects android/app/build.gradle file (inside the dependencies { .. } block).

  • Messaging only: If you added the previous versions intent-filter to your android/app/src/main/AndroidManifest.xml file, remove it:

- <intent-filter>
- <action android:name="FLUTTER_NOTIFICATION_CLICK" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
  • Messaging only: Messaging now supports v2 embedding, it's recommended that you upgrade your Flutter app to use v2 embedding if you haven't done so already.
  • If your can't upgrade to v2 embedding yet, there are some additional manual steps you'll need to do before you can use messaging in your app. Please see the Android section of the FlutterFire Messaging documentation for more information.
  • If you were using v1 embedding on the previous version of messaging then note that the java class name has changed to FlutterFirebaseMessagingBackgroundService from FlutterFirebaseMessagingService and you may need to update this in your file.

B. iOS Installation#

These steps can also apply to macOS.

  • If you manually import Firebase and configure it via [FIRApp configure]; or FirebaseApp.configure() within your projects ios/{projectName}/AppDelegate{.m/.swift} file, you can now safely remove it - FlutterFire automatically handles this for you.

  • Crashlytics only: Open your ios/Runner.xcworkspace workspace file with Xcode.

    1. From Xcode select Runner from the left-hand side project navigation.
    2. Select the Build Phases tab in the middle pane.
    3. Find a script in the list of Build Phases that contains ${PODS_ROOT}/Fabric/run as the shell script. Once located, press the x on the right of the row to remove that script. If you can't find one then you can ignore this step.
  • Crashlytics only: Follow the new iOS integration steps shown in the FlutterFire Crashlytics installation documentation .

  • If you face CocoaPods issues when building, follow the steps below in the CocoaPods could not find compatible versions for pod section.

  • Messaging only: If you previously added the FirebaseAppDelegateProxyEnabled key with a false value to your Info.plist to disable swizzling; you can now remove it, the plugin now supports multiple delegates and will internally forward to any other plugins that may have previously registered a delegate.

  • Additionally, swizzling is now no longer used on iOS and the plugin calls addApplicationDelegate on the FlutterPlugin Registrar instead. It is required for macOS however as the macOS registrar does not support addApplicationDelegate.

C. Web Installation#

4. Initialize FlutterFire#

To ensure each plugin has a consistent API and to enable the possibility of some new features, you are now required to initialize FlutterFire before performing any other Firebase related functionality.

The firebase_core package exposes a Firebase class, provides an initializeApp method. This method should be called as soon as possible in your application. It is responsible for ensuring the default app is ready, and bootstraps all additional FlutterFire plugins which are installed.

To learn more, view the Initializing FlutterFire documentation.

Plugin Usage#

Each plugin now provides a consistent API for integrating with Firebase. The example below shows how the cloud_firestore package previously created a new instance vs the new way:

// Before
Firestore firestore = Firestore();
// After
FirebaseFirestore firestore = FirebaseFirestore.instance;

If you'd like to a plugin with a secondary Firebase application, use the instanceFor method instead:

FirebaseApp secondaryApp ='SecondaryApp');
// Before
Firestore firestore = Firestore(app: secondaryApp);
// After
FirebaseFirestore firestore = FirebaseFirestore.instanceFor(app: secondaryApp);

To learn more about secondary Firebase app instances, view the Initializing secondary apps documentation.

Plugin Changes#


  • DEPRECATED: FirebaseApp.configure method is now deprecated in favor of the Firebase.initializeApp method.

  • DEPRECATED: FirebaseApp.allApps method is now deprecated in favor of the Firebase.apps property.

    • Previously, allApps was asynchronous & is now synchronous.
  • DEPRECATED: FirebaseApp.appNamed method is now deprecated in favor of the method.

  • BREAKING: FirebaseApp.options getter is now synchronous.

  • FirebaseOptions has been reworked to better match web property names:

    • DEPRECATED: googleAppID is now deprecated in favor of appId.
    • DEPRECATED: projectID is now deprecated in favor of projectId.
    • DEPRECATED: bundleID is now deprecated in favor of bundleId.
    • DEPRECATED: clientID is now deprecated in favor of androidClientId.
    • DEPRECATED: trackingID is now deprecated in favor of trackingId.
    • DEPRECATED: gcmSenderID is now deprecated in favor of messagingSenderId.
    • Added support for authDomain.
    • Added support for trackingId.
    • Required properties are now apiKey, appId, messagingSenderId & projectId.
  • Added support for deleting Firebase app instances via the delete method on FirebaseApp.

  • iOS: The default Firebase app is now automatically configured without needing to manually add Objective-C code to your iOS application.

  • Added support for returning consistent error messages from firebase-dart plugin.

    • Any FlutterFire related errors now throw a FirebaseException.
  • Added a FirebaseException class to handle all FlutterFire related errors.

    • Matching the web sdk, the exception returns a formatted "[plugin/code] message" message when thrown.
  • Added support for setAutomaticDataCollectionEnabled & isAutomaticDataCollectionEnabled on a FirebaseApp instance.

  • Added support for setAutomaticResourceManagementEnabled on a FirebaseApp instance.

  • Android: Gradle build tools updated to 3.5.0 from 3.3.0.

  • Android: Removed Gradle ‘hacks’ and upgrade Flutter SDK requirement from >=1.12.13+hotfix.4 to >=1.12.13+hotfix.5

  • Android: Switched to using Firebase BoM to manage SDK versions


Overall, Firebase Auth has been heavily reworked to bring it inline with the federated plugin setup along with adding new features, documentation and many more unit and end-to-end tests. The API has mainly been kept the same, however there are some breaking changes.

  • General:

    • BREAKING: The FirebaseUser class has been renamed to User.
    • BREAKING: The AuthResult class has been renamed to UserCredential.
    • NEW: The ActionCodeSettings class is now consumable on all supporting methods.
      • NEW: Added support for the dynamicLinkDomain property.
    • NEW: Added a new FirebaseAuthException class (extends FirebaseException).
      • All errors are now returned as a FirebaseAuthException, allowing you to access the code & message associated with the error.
      • In addition, it is now possible to access the email and credential properties on exceptions if they exist.
      • BREAKING: Error codes previously in the format ERROR_WRONG_PASSWORD are now in the format wrong-password.
  • FirebaseAuth

    • BREAKING: Accessing the current user via currentUser() is now synchronous via the currentUser getter.
    • BREAKING: isSignInWithEmailLink() is now synchronous.
    • BREAKING: EmailAuthProvider.providerId is now EmailAuthProvider.PROVIDER_ID.
    • DEPRECATED: FirebaseAuth.fromApp() is now deprecated in favor of FirebaseAuth.instanceFor().
    • DEPRECATED: onAuthStateChanged has been deprecated in favor of authStateChanges().
    • NEW: Added support for idTokenChanges() stream listener.
    • NEW: Added support for userChanges() stream listener.
      • The purpose of this API is to allow users to subscribe to all user events without having to manually hydrate app state in cases where a manual reload was required (e.g. updateProfile()).
    • NEW: Added support for applyActionCode().
    • NEW: Added support for checkActionCode().
    • NEW: Added support for verifyPasswordResetCode().
    • NEW: Added support for accessing the current language code via the languageCode getter.
    • NEW: setLanguageCode() now supports providing a null value.
      • On web platforms, if null is provided the Firebase projects default language will be set.
      • On native platforms, if null is provided the device language will be used.
    • NEW: verifyPhoneNumber() exposes a autoRetrievedSmsCodeForTesting property.
      • This allows developers to test automatic SMS code resolution on Android devices during development.
    • NEW (iOS): appVerificationDisabledForTesting setting can now be set for iOS.
      • This allows developers to skip ReCaptcha verification when testing phone authentication.
    • NEW (iOS): userAccessGroup setting can now be set for iOS & macOS.
      • This allows developers to share authentication states across multiple apps or extensions on iOS & macOS. For more information see the Firebase iOS SDK documentation.
  • User

    • BREAKING: Removed the UpdateUserInfo class when using updateProfile in favor of named arguments.
    • NEW: Added support for getIdTokenResult().
    • NEW: Added support for verifyBeforeUpdateEmail().
    • FIX: Fixed several iOS crashes when the Firebase SDK returned nil property values.
    • FIX: Fixed an issue on Web & iOS where a user's email address would still show after unlinking the email/password provider.
  • UserCredential

    • NEW: Added support for accessing the user's AuthCredential via the credential property.
  • AuthProvider & AuthCredential

    • DEPRECATED: All sub-class (e.g. GoogleAuthProvider) getCredential() methods have been deprecated in favor of credential().
      • DEPRECATED: EmailAuthProvider.getCredentialWithLink() has been deprecated in favor of EmailAuthProvider.credentialWithLink().
    • NEW: Supporting providers can now assign scope and custom request parameters.
      • The scope and parameters will be used on web platforms when triggering a redirect or popup via signInWithPopup() or signInWithRedirect().


  • BREAKING: Removal of Fabric SDKs and migration to the new Firebase Crashlytics SDK.
  • BREAKING: The following methods have been removed as they are no longer available on the Firebase Crashlytics SDK:
    • setUserEmail
    • setUserName
    • getVersion
    • isDebuggable
  • BREAKING: log now returns a Future. Calling log now sends logs immediately to the underlying Crashlytics SDK instead of pooling them in Dart.
  • BREAKING: the methods setInt, setDouble, setString and setBool have been replaced by setCustomKey.
    • setCustomKey returns a Future. Calling setCustomKey now sends custom keys immediately to the underlying Crashlytics SDK instead of pooling them in Dart.
  • DEPRECATED: enableInDevMode has been deprecated, use isCrashlyticsCollectionEnabled and setCrashlyticsCollectionEnabled instead.
  • DEPRECATED: Crashlytics has been deprecated, use FirebaseCrashlytics instead.
  • NEW: Custom keys that are automatically added by FlutterFire when calling reportError are now prefixed with flutter_error_.
  • NEW: Calling .crash() on Android & iOS/macOS now reports a custom named exception to the Firebase Console. This allows you to easily locate test crashes.
    • Name: FirebaseCrashlyticsTestCrash.
    • Message: This is a test crash caused by calling .crash() in Dart..
  • NEW: recordError now uses a named native exception when reporting to the Firebase Console. This allows you to easily locate errors originating from Flutter.
    • Name: FlutterError.
  • NEW: Added support for checkForUnsentReports.
    • Checks a device for any fatal or non-fatal crash reports that haven't yet been sent to Crashlytics.
    • See reference API docs for more information.
  • NEW: Added support for deleteUnsentReports.
    • If automatic data collection is disabled, this method queues up all the reports on a device for deletion.
    • See reference API docs for more information.
  • NEW: Added support for didCrashOnPreviousExecution.
    • Checks whether the app crashed on its previous run.
    • See reference API docs for more information.
  • NEW: Added support for sendUnsentReports.
    • If automatic data collection is disabled, this method queues up all the reports on a device to send to Crashlytics.
    • See reference API docs for more information.
  • NEW: Added support for setCrashlyticsCollectionEnabled.
    • Enables/disables automatic data collection by Crashlytics.
    • See reference API docs for more information.
  • NEW: Added support for isCrashlyticsCollectionEnabled.
    • If the current Crashlytics instance is collecting reports - if false, then no crash reporting data is sent to Firebase.
    • See reference API docs for more information.
  • FIX: Fixed a bug that prevented keys from being set on iOS devices.


Along with the below changes, the plugin has undergone a quality of life update to better support exceptions thrown. Any Firestore specific errors now return a FirebaseException (see Core changes), allowing you to directly access the code (e.g. permission-denied) and message.

  • FirebaseFirestore:

    • NEW: Add useFirestoreEmulator(String host, int port) support.
    • BREAKING: Calling settings() now accepts a Settings instance.
    • DEPRECATED: Calling document() is deprecated in favor of doc().
    • DEPRECATED: Calling Firestore(app: app) is now deprecated. Use FirebaseFirestore.instance or FirebaseFirestore.instanceFor instead.
    • BREAKING: enablePersistence has now been removed, see settings() instead.
    • NEW: Add clearPersistence() support.
    • NEW: Add disableNetwork() support.
    • NEW: Add enableNetwork() support.
    • NEW: Add snapshotInSync() support.
    • NEW: Add terminate() support.
    • NEW: Add waitForPendingWrites() support.
  • CollectionReference:

    • BREAKING: Getting a collection parent document via parent() has been changed to a getter parent.
    • DEPRECATED: Calling document() is deprecated in favor of doc().
  • Query:

    • BREAKING: The internal query logic has been overhauled to better assert invalid queries locally.
    • BREAKING: getDocuments/get has been updated to accept an instance of GetOptions (see below).
    • DEPRECATED: Calling getDocuments() is deprecated in favor of get().
    • NEW: Query methods are now chainable.
    • NEW: It is now possible to call same-point cursor based queries without throwing (e.g. calling endAt() and then endBefore() will replace the "end" cursor query with the endBefore).
    • NEW: Added support for limitToLast.
  • QuerySnapshot:

    • DEPRECATED: documents has been deprecated in favor of docs.
    • DEPRECATED: documentChanges has been deprecated in favor of docChanges.
    • NEW: docs now returns a List<QueryDocumentSnapshot> vs List<DocumentSnapshot>. This doesn't break existing functionality.
  • DocumentReference:

    • BREAKING: setData/set has been updated to accept an instance of SetOptions (see below, supports mergeFields).
    • BREAKING: get() has been updated to accept an instance of GetOptions (see below).
    • BREAKING: Getting a document parent collection via parent() has been changed to a getter parent.
    • DEPRECATED: documentID has been deprecated in favor of id.
    • DEPRECATED: setData() has been deprecated in favor of set().
    • DEPRECATED: updateData() has been deprecated in favor of update().
  • DocumentSnapshot:

    • BREAKING: Getting a snapshots' data via the data getter is now done via the data() method.
    • DEPRECATED: documentID has been deprecated in favor of id.
    • NEW: Added support for fetching nested snapshot data via the get() method. If no data exists at the given path, a StateError will be thrown.
  • DocumentChange:

    • DEPRECATED: Calling document() is deprecated in favor of doc().
  • WriteBatch:

    • BREAKING: setData/set now supports SetOptions to merge data/fields (previously this accepted a Map).
    • DEPRECATED: setData() has been deprecated in favor of set().
    • DEPRECATED: updateData() has been deprecated in favor of update().
  • Transaction:

    • BREAKING: Transactions have been overhauled to address a number of issues:
      • Values returned from the transaction will now be returned from the Future. Previously, only primitive values ( e.g. String) were supported. It is now possible to return values such as a DataSnapshot.
      • When manually throwing an exception, the context was lost and a generic PlatformException was thrown. You can now throw & catch on any exceptions.
      • The modify methods on a transaction (set, delete, update) were previously Futures. This has been updated to better reflect how transactions should behave - they are now synchronous and are executed atomically once the transaction handler block has finished executing.
  • FieldPath:

    • NEW: The constructor has now been made public to accept a List of String values. Previously field paths were accessible only via a dot-notated string path. This meant attempting to access a field in a document with a . in the name (e.g. was impossible.
  • GetOptions: New class created to support how data is fetched from Firestore (server, cache, serverAndCache).

  • SetOptions: New class created to both merge and mergeFields when setting data on documents.

  • GeoPoint:

    • BREAKING: Added latitude and longitude validation when constructing a new GeoPoint instance.


  • FirebaseFunctions:

    • DEPRECATED: useFunctionsEmulator({required String origin}) parameters have been changed in line with every other package emulator API; useFunctionsEmulator(String host, int port).
    • DEPRECATED: Class CloudFunctions is now deprecated. Use FirebaseFunctions instead.
    • DEPRECATED: Calling CloudFunctions.instance or CloudFunctions(app: app, region: region) is now deprecated. Use FirebaseFunctions.instance or FirebaseFunctions.instanceFor(app: app, region: region) instead.
    • DEPRECATED: Calling getHttpsCallable(functionName: functionName) is deprecated in favor of httpsCallable(functionName)
    • DEPRECATED: CloudFunctionsException is deprecated in favor of FirebaseFunctionsException.
    • NEW: FirebaseFunctionsException now exposes a details property to retrieve any additional data provided with the exception returned by an HTTPS callable function.
    • NEW: Internally, instances of FirebaseFunctions are now cached and lazily loaded.
    • NEW: httpsCallable accepts an instance of HttpsCallableOptions (see below).
  • HttpsCallable:

    • DEPRECATED: Setting timeout is deprecated in favor of using HttpsCallableOptions (see below).
  • HttpsCallableResult:

    • BREAKING: data is now read-only, only its getter is exposed.
    • FIX: HttpsCallableResult's data property can now return a Map, List or a primitive value. Previously the Web implementation incorrectly assumed that a Map was always returned by the HTTPS callable function.
  • HttpsCallableOptions:

    • NEW: This new class has been created to support setting options for httpsCallable instances.


This plugin is now federated to allow integration with other platforms, along with upgrading underlying SDK versions.

We've also added lots of features which can be seen in the changelog below, however notably the biggest changes are:

  • Removed all manual native code changes that were originally required for integration - this plugin works out of the box once configured with Firebase & APNs.

  • Support for macOS.

  • iOS background handler support.

  • Android background handler debugging and logging support.

  • Android V2 embedding support.

  • Reworked API for message handling (Streams + explicit handlers).

  • Fully typed Message & Notification classes (vs raw Maps).

  • New Apple notification permissions & support.

  • Detailed documentation.

  • FirebaseMessaging:

    • BREAKING: configure() has been removed in favor of calling specific static methods which return Streams.
      • Why?: The previous implementation of configure() caused unintended side effects if called multiple times (either to register a different handler, or remove handlers). This change allows developers to be more explicit about registering handlers and removing them without effecting others via Streams.
    • DEPRECATED: Calling FirebaseMessaging() has been deprecated in favor of FirebaseMessaging.instance & FirebaseMessaging.instanceFor().
    • DEPRECATED: requestNotificationPermissions() has been deprecated in favor of requestPermission().
    • DEPRECATED: deleteInstanceID() has been deprecated in favor of deleteToken().
    • DEPRECATED: autoInitEnabled() has been deprecated in favor of isAutoInitEnabled.
    • NEW: Added support for isAutoInitEnabled as a synchronous getter.
    • NEW: Added support for getInitialMessage(). This API has been added to detect whether a messaging containing a notification has caused the application to be opened via users interaction.
    • NEW: Added support for deleteToken().
    • NEW: Added support for getToken().
    • NEW: [Apple] Added support for getAPNSToken().
    • NEW: [Apple] Added support for getNotificationSettings(). See NotificationSettings below.
    • NEW: [Apple] Added support for requestPermission(). See NotificationSettings below. New permissions such as carPlay, crtiticalAlert, announcement are now supported.
    • NEW: [Android] Added support for sendMessage(). The sendMessage() API enables support for sending FCM payloads back to a custom server from the device.
    • NEW: [Android] When receiving background messages on the separate background Dart executor whilst in debug, you should now see flutter logs and be able to debug/add breakpoints your Dart background message handler.
    • NEW: [Apple] Added support for setForegroundNotificationPresentationOptions(). By default, iOS devices will not show notifications in the foreground. Use this API to override the defaults. See documentation for Android foreground notifications.
    • NEW - [Android] Firebase Cloud Messages that contain a notification are now always sent to Dart regardless of whether the app was in the foreground or background. Previously, if a message came through that contained a notification whilst your app was in the foreground then FCM would not notify the plugin messaging service of the message (and subsequently your handlers in Dart) until the user interacted with it.
  • Event handling:

    • Event handling has been reworked to provide a more intuitive API for developers. Foreground based events can now be accessed via Streams:
      • NEW: FirebaseMessaging.onMessage Returns a Stream that is called when an incoming FCM payload is received whilst the Flutter instance is in the foreground, containing a [RemoteMessage].
      • NEW: FirebaseMessaging.onMessageOpenedApp Returns a [Stream] that is called when a user presses a notification displayed via FCM. This replaces the previous onLaunch and onResume handlers.
      • NEW: FirebaseMessaging.onBackgroundMessage() Sets a background message handler to trigger when the app is in the background or terminated.
  • IosNotificationSettings:

    • DEPRECATED: Usage of the IosNotificationSettings class is now deprecated (currently used with the now deprecated requestNotificationPermissions() method).
      • Instead of this class, use named arguments when calling requestPermission() and read the permissions back via the returned NotificationSettings instance.
  • NotificationSettings:

    • NEW: A NotificationSettings class is returned from calls to requestPermission() and getNotificationSettings(). It contains information such as the authorization status, along with the platform specific settings.
  • RemoteMessage:

    • NEW: Incoming FCM payloads are now represented as a RemoteMessage rather than a raw Map.
  • RemoteNotification:

    • NEW:When a message includes a notification payload, the RemoteMessage includes a RemoteNotification rather than a raw Map.
  • Other:

    • Additional types are available throughout messaging to aid with the latest changes:
      • BackgroundMessageHandler, AppleNotificationSetting, AppleShowPreviewSetting, AuthorizationStatus , AndroidNotificationPriority, AndroidNotificationVisibility

Remote Config#

The plugin has been updated and reworked to better mirror the features currently offered by the native (iOS and Android) clients.


  • CHORE: migrate to platform interface.
  • FEAT: support multiple firebase apps. RemoteConfig.instanceFor() can be used to retrieve an instance of RemoteConfig for a particular Firebase App.
  • BREAKING: fetch() now takes no arguments. RemoteConfigSettings should be used to specify the freshness of the cached config via the minimumFetchInterval property.
  • BREAKING: activateFetched() is now activate().
  • FEAT: Added fetchAndActivate() support.
  • FEAT: Added ensureInitialized() support.


  • BREAKING: fetchTimeoutMillis is now fetchTimeout.
  • BREAKING: minimumFetchIntervalMillis is now minimumFetchInterval
  • BREAKING: fetchTimeout and minimumFetchInterval are refactored from int to Duration.


  • BREAKING: removed FetchThrottledException. The general FirebaseException is used to handle all RemoteConfig specific exceptions.


Overall, Firebase Storage has been heavily reworked to bring it inline with the federated plugin setup along with adding new features, documentation and many more unit and end-to-end tests (tested on Android, iOS & macOS).

  • FirebaseStorage:

    • DEPRECATED: Constructing an instance is now deprecated, use FirebaseStorage.instanceFor or FirebaseStorage.instance instead.
    • DEPRECATED: getReferenceFromUrl() is deprecated in favor of calling ref() with a path.
    • DEPRECATED: getMaxOperationRetryTimeMillis() is deprecated in favor of the getter maxOperationRetryTime.
    • DEPRECATED: getMaxUploadRetryTimeMillis() is deprecated in favor of the getter maxUploadRetryTime.
    • DEPRECATED: getMaxDownloadRetryTimeMillis() is deprecated in favor of the getter maxDownloadRetryTime.
    • DEPRECATED: setMaxOperationRetryTimeMillis() is deprecated in favor of setMaxUploadRetryTime().
    • DEPRECATED: setMaxUploadRetryTimeMillis() is deprecated in favor of setMaxUploadRetryTime().
    • DEPRECATED: setMaxDownloadRetryTimeMillis() is deprecated in favor of setMaxDownloadRetryTime().
    • NEW: To match the Web SDK, calling ref() creates a new Reference at the bucket root, whereas an optional path (ref('/foo/bar.png')) can be used to create a Reference pointing at a specific location.
    • NEW: Added support for refFromURL, which accepts a Google Storage (gs://) or HTTP URL and returns a Reference synchronously.
  • Reference:

    • BREAKING: StorageReference has been renamed to Reference.
    • DEPRECATED: getParent() is deprecated in favor of .parent.
    • DEPRECATED: getRoot() is deprecated in favor of .root.
    • DEPRECATED: getStorage() is deprecated in favor of .storage.
    • DEPRECATED: getBucket() is deprecated in favor of .bucket.
    • DEPRECATED: getPath() is deprecated in favor of .fullPath.
    • DEPRECATED: getName() is deprecated in favor of .name.
    • NEW: Added support for list(options).
      • Includes ListOptions API (see below).
    • NEW: Added support for listAll().
    • NEW: putString() has been added to accept a string value, of type Base64, Base64Url, a Data URL or raw strings.
      • Data URLs automatically set the Content-Type metadata if not already set.
    • NEW: getData() does not require a maxSize, it can now be called with a default of 10mb.
  • NEW ListOptions:

    • The list() method accepts a ListOptions instance with the following arguments:
      • maxResults - limits the number of results returned from a call. Defaults to 1000.
      • pageToken - a page token returned from a ListResult - used if there are more items to query.
  • NEW ListResult:

    • A ListResult class has been added, which is returned from a call to list() or listAll(). It exposes the following properties:
      • items (List<Reference>): Returns the list of reference objects at the current reference location.
      • prefixes (List<Reference>): Returns the list of reference sub-folders at the current reference location.
      • nextPageToken (String): Returns a string (or null) if a next page during a list() call exists.
  • Tasks:

    • Tasks have been overhauled to be closer to the expected Firebase Web SDK Storage API, allowing users to access and control ongoing tasks easier. There are a number of breaking changes & features with this overhaul:
      • BREAKING: StorageUploadTask has been renamed to UploadTask (extends Task).
      • BREAKING: StorageDownloadTask has been renamed to DownloadTask (extends Task).
      • BREAKING: StorageTaskEvent has been removed (see below).
      • BREAKING: StorageTaskSnapshot has been renamed to TaskSnapshot.
      • BREAKING: pause(), cancel() and resume() are now Futures which return a boolean value to represent whether the status update was successful.
        • Previously, these were void methods but still carried out an asynchronous tasks, potentially leading to uncaught exceptions.
      • BREAKING: isCanceled, isComplete, isInProgress, isPaused and isSuccessful have now been removed. Instead, you should subscribe to the stream (for paused/progress/complete/error events) or the task Future for task completion/errors.
      • Additionally, the latest TaskSnapshot now provides the latest TaskState via task.snapshot.state.
      • BREAKING: The events stream (now snapshotEvents) previously returned a StorageTaskEvent, containing a StorageTaskEventType and StorageTaskSnapshot Instead, the stream now returns a TaskSnapshot which includes the state.
      • BREAKING: A task failure and cancellation now throw a FirebaseException instead of a new event.
      • DEPRECATED: events stream is deprecated in favor of snapshotEvents.
      • DEPRECATED: lastSnapshot is deprecated in favor of snapshot.


The new Tasks API matches the Web SDK API, for example:

UploadTask task = FirebaseStorage.instance.ref('/notes.text').putString('My notes!');
// Optional
task.snapshotEvents.listen((TaskSnapshot snapshot) {
print('Snapshot state: ${snapshot.state}'); // paused, running, complete
print('Progress: ${snapshot.totalBytes / snapshot.bytesTransferred}');
}, onError: (Object e) {
print(e); // FirebaseException
// Optional
.then((TaskSnapshot snapshot) {
print('Upload complete!');
.catchError((Object e) {
print(e); // FirebaseException

Subscribing to Stream updates and/or the tasks delegating Future is optional - if you require progress updates on your task use the Stream, otherwise the Future will resolve once it's complete. Using both together is also supported.

Common Upgrade Issues#

CocoaPods could not find compatible versions for pod#

This issue can happen when you upgrade your FlutterFire packages and attempt to build for iOS or macOS, this is usually down to one of the following:

  • Your Podfile.lock version inside your iOS or macOS directory is out of date and locked to older versions of the Firebase iOS SDKs whereas the newly upgraded FlutterFire packages might be using newer versions of these SDKs.
    • Solution: Delete the Podfile.lock file and try your build again. This file will get regenerated after the next pod install.
  • Your pod specs repo is out of date, meaning CocoaPods locally isn't aware of any potential newer versions of the Firebase iOS SDKs that have been recently published.
    • Solution: Run pod repo update in your terminal and try your build again.