# `firebase_core`

| Package | Kind | Provides the role | Needs | Choose with |
| --- | --- | --- | --- | --- |
| [`smf_firebase_core`](https://pub.dev/packages/smf_firebase_core) | infrastructure | none | nothing | `-m firebase_core` |

`firebase_core` sets up [Firebase](https://firebase.google.com/docs/flutter/setup) with [firebase_core](https://pub.dev/packages/firebase_core), which the other Firebase packages of an app build on. [`firebase_crashlytics`](https://doc.saymyframe.com/modules/firebase-crashlytics.md), [`firebase_analytics`](https://doc.saymyframe.com/modules/firebase-analytics.md), [`firebase_messaging`](https://doc.saymyframe.com/modules/firebase-messaging.md) and [`firebase_auth`](https://doc.saymyframe.com/modules/firebase-auth.md) depend on it, so it comes with them.

## What it adds to the app

The module adds `firebase_core: ^4.15.0` to the dependencies, and `lib/firebase_options.dart` with `DefaultFirebaseOptions`, the options of the Firebase app of each platform. Until `flutterfire configure` runs, the file is a placeholder in the form that flutterfire_cli writes for an app with no platform configured. Each platform throws an `UnsupportedError`, so the app compiles but stops at start-up.

In the platform phase of `bootstrap()`, before the services of the app, it initializes Firebase:

```dart
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
```

It also asks for iOS 15.0 or newer, the lowest version that the Firebase SDKs support, which the app has already. It adds a section on Firebase to the README of the app, which explains how to configure the app again, such as for another Firebase project or on another machine.

The [guide for coding agents](https://doc.saymyframe.com/guides/coding-agents.md) of the app gets a section "Firebase" too. It says that the options are a placeholder until `flutterfire configure` writes them, that an agent runs that command only when asked, and that a test which runs `main()` or `bootstrap()` starts Firebase.

## The machine

Before generation, the module checks what `flutterfire configure` needs: the Firebase CLI, a login of the Firebase CLI that Google still accepts, flutterfire_cli 1.4.1 or a later 1.x activated globally, and on macOS the Ruby gem xcodeproj 1.23.0 or newer. On other systems it warns that the Xcode project has to be set up on a Mac. A missing tool is a warning with instructions. In a terminal, SMF offers to install the Firebase CLI, to log in (or to log in again when the login has expired) and to activate flutterfire_cli, and asks before each. See [Firebase](https://doc.saymyframe.com/guides/firebase.md#before-generation-the-machine).

For the modules that depend on it, the package has one more check, `FirebaseCliVersionCheck`. A module whose command exists only in newer versions of the Firebase CLI puts it among its own checks of the machine, with the lowest version that has the command, as `firebase_auth` does with 15.34.0. The check reads `firebase --version` and tells how to update an older Firebase CLI, which SMF does not update itself. On a machine without the Firebase CLI, the check of `firebase_core` runs first and offers the installation, and the check of the version then reads the version that was installed. See [a check from the module you depend on](https://doc.saymyframe.com/extending/infrastructure-module.md#a-check-from-the-module-you-depend-on).

## After generation

Once the app has its packages, the module runs `flutterfire configure` in it with the terminal, after asking:

```bash
dart pub global run flutterfire_cli:flutterfire configure --platforms=android,ios --overwrite-firebase-options --ios-bundle-id=<bundle id> --android-package-name=<application id>
```

The FlutterFire CLI asks for the Firebase project and writes the options into `lib/firebase_options.dart`. The module publishes the id of this step as `FirebaseCoreModule.configureStep`, so that the modules that depend on it can [continue the step](https://doc.saymyframe.com/extending/infrastructure-module.md#continuing-a-step) with steps of their own. `firebase_crashlytics` continues it with a fix of a file that flutterfire writes, and `firebase_auth` with the script that enables the sign-in methods in the project that you chose. Those steps run right after it succeeds.

A run without a terminal, a run that skips external setup, and a run that lacks what `flutterfire configure` needs print the command to run later instead, followed by the commands of the steps that continue it. See [Firebase](https://doc.saymyframe.com/guides/firebase.md#after-generation-flutterfire-configure).

## Choosing it

`smf create` asks which infrastructure modules the app has, and offers this one. It also comes with the other Firebase modules. To choose it without the question:

```bash
smf create my_app -m firebase_core
```
