Cloud Environments
Before You Begin
This guide builds upon the concepts and implementations from previous guides, particularly the Navigation & Route Security guide. If you haven't completed the previous guides, you can start with the repository that ended off at the last guide by cloning https://github.com/JLogical-Apps/flood-template/tree/routing (opens in a new tab).
Reminder of Environments
Throughout our development process, we've been primarily using the testing
environment. However, Flood provides several other environments to facilitate different stages of development and deployment:
testing
: Simulates all services in-memory, resetting everything on app restart.device
: Simulates services on the device's file system, persisting data between app restarts.qa
: Prefers to use predefined emulators for services like Firebase.production
: Uses online resources such as Firebase or Appwrite.
In this guide, we'll focus on setting up the production
environment to link our app to a Firebase project. This will allow us to start testing our data in the cloud and move towards a more realistic production scenario.
Integrating with Firebase
For this guide, we'll be integrating our app with Firebase (opens in a new tab). Firebase offers a suite of tools that work well with Flutter apps, including Authentication, Firestore (for database), and Storage. If you're not familiar with these Firebase services, it's recommended to review the Firebase documentation (opens in a new tab) before proceeding.
For more details on how Flood integrates with Firebase, you can refer to the Firebase integration guide.
Firebase Project Creation
Let's start by creating a new Firebase project:
- Go to the Firebase Console (opens in a new tab).
- Click on "Add project" and follow the prompts to create a new project.
- Once your project is created, we need to set up the services we'll be using:
a. Enable Email/Password authentication:
- In the Firebase Console, go to "Authentication" > "Sign-in method".
- Enable the Email/Password sign-in method.
b. Create Firestore database:
- Go to "Firestore Database" in the Firebase Console.
- Click "Create database".
- Start in test mode for now (we'll add security rules later).
c. Set up Firebase Storage:
- Go to "Storage" in the Firebase Console.
- Click "Get started".
- Start in test mode (we'll add security rules later).
Link Project to Flood
Now that we have our Firebase project set up, let's link it to our Flood app:
-
From your app project directory (for example,
cd example
), install and use the flutterfire (opens in a new tab) CLI to configure your project:dart pub global activate flutterfire_cli flutterfire configure
If you encounter errors with the latest version of flutterfire
, you can use version 0.2.7 instead:
dart pub global activate flutterfire_cli 0.2.7
flutterfire configure
-
Create a
firebase
directory in your core project (for example,example_core
). -
From within the
firebase
directory, run:firebase init
This will initialize and link to the Firebase project you created. When prompted, select Firestore, Functions, Storage, and Emulators for initialization.
-
Modify your
main.dart
file to includeFirebaseCoreComponent
ininitialCoreComponents
:example/lib/main.dart... final corePondContext = await getCorePondContext( initialCoreComponents: (context) => [ FirebaseCoreComponent(app: DefaultFirebaseOptions.currentPlatform), ], ... ); ...
The
FirebaseCoreComponent
will run Firebase.initializeApp (opens in a new tab) before the rest of the CorePondComponents register, which is necessary for proper Firebase integration. -
Integrate Auth and Repository cloud implementations:
When using
adapting
AuthService
andRepository
s in Flood, Flood will use thecloud
variants when in a cloud environment likeproduction
. However, thesecloud
variants don't actually integrate with a specific cloud service by default. Instead, they look for correspondingAuthServiceImplementation
andRepositoryImplementation
to determine how to interact with the cloud service.By passing in
FirebaseCloudRepositoryImplementation
andFirebaseAuthServiceImplementation
, we're explicitly telling Flood to use Firebase as the backend for our cloud repositories and authentication services.Here's how to set it up:
example_core/lib/pond.dart... final corePondContext = await getCorePondContext( initialCoreComponents: (context) => [ FirebaseCoreComponent(app: DefaultFirebaseOptions.currentPlatform), ], repositoryImplementations: (context) => [ FirebaseCloudRepositoryImplementation(), ], authServiceImplementations: (context) => [ FirebaseAuthServiceImplementation(), ], ... ); ...
By setting up these implementations, you're effectively creating a bridge between your Flood app's abstract data layer and the concrete Firebase services. This allows your app to work with Firebase seamlessly when in the
production
environment, while still being able to use local implementations in other environments liketesting
ordevice
.
Running in Production
Now that we've set up our Firebase integration, let's run our app in the production environment:
-
Change your environment to
production
by updating yourexample/assets/config.overrides.yaml
file:example/assets/config.overrides.yamlenvironment: production
-
Re-run your app.
-
Try signing up and creating todos. You should notice that everything is now linking to your Firebase project!
You may need to create indexes for some queries. If you see errors in your debug console related to missing indexes, follow the provided links to create the necessary indexes in your Firebase project.
Next Steps
Congratulations! You've successfully set up your Flood app to work with Firebase in a production environment. However, our current setup leaves our Firebase project exposed, allowing anyone to access all the data. To address this security concern, we need to implement proper security rules to protect our users' data.
In the next guide, Data Security, we'll explore how to secure our repositories and ensure that users can only access their own data. This is a crucial step in preparing your app for real-world use.