26

I am trying to figure out how to set up different firebase environments in a flutter project.

I understand how to do this in firebase, I created two projects, one for production, one for the test. Then, in an iOS or Android project, I could use various methods to switch between these two environments using separate google-services.json or GoogleServices-Info.plist files.

In Flutter I found this description of how to separate environments, but it only explains how to differentiate between environments in the flutter code.

How can I get this environment to change what iOS and Android build at compile time? It would even be sufficient simply to allow a file copy hook at build time.

Samet ÖZTOPRAK
  • 3,112
  • 3
  • 32
  • 33
Daniel Brotherston
  • 1,954
  • 4
  • 18
  • 28

6 Answers6

4

You can switch accounts using FirebaseApp.configure. You can offer your own solution or secret dev panel to switch between them.

The solutions with build flavours are horrible, and plist implementations will lock you into builds when you deploy for TestFlight + they are messy and slow.

Here's an example without silly build flavours: (You could use Assets as well.)

// Load a named file.
let filePath = Bundle.main.path(forResource: "MyGoogleService", ofType: "plist")
guard let fileopts = FirebaseOptions(contentsOfFile: filePath!)
  else { assert(false, "Couldn't load config file") }
FirebaseApp.configure(options: fileopts)
Oliver Dixon
  • 7,012
  • 5
  • 61
  • 95
  • Do you have an example of doing this with Dart code? I don't see an option for `FirebaseOptions` to take `contentsOfFile`. I do see the option to pass individual properties but not all properties in the json/plist service files are accepted by `FirebaseOptions` in Flutter. – jdixon04 Jun 23 '21 at 19:00
  • @jdixon04 they fixed a lot of that. It should fully function now. – Oliver Dixon Aug 29 '23 at 08:05
3

I wrote an article about how to do this for Firebase configuration as well as runtime configuration in dart code using flavors and platform channels.

https://medium.com/@matt.goodson.business/separating-build-environment-configurations-in-flutter-with-firebase-doing-it-the-right-way-c72c3ad3621f

Flutter flavors work pretty seamlessly with Android flavors. For iOS you need to create Xcode schemes for each flavor and link them to build configurations.

For dart configuration, you can use platform channels to get the flavor used during the build at runtime. This lets you configure the app without having multiple main.dart files or passing a target argument.

Matt
  • 688
  • 5
  • 15
  • 2
    Hey, you don't need to do this. You can load different files at runtime. See my answer. Building flavours are terrible, how will QA test TestFlight builds for example and many other problems. – Oliver Dixon Jul 24 '20 at 10:21
1

Salvatore Giordano has written a blog post with a detailed description of how to achieve this:

https://medium.com/@salvatoregiordanoo/flavoring-flutter-392aaa875f36

Flutter accepts a parameter --flavor=<flavor> which allows you to select different build flavors. In Android this works as expected, selecting different build flavors. IOS is a little tricker because a scheme is needed for every flavor, and the build configurations in the form of Release-<flavor> are also needed.

Once these parts are in place, they can be used, to select the firebase configuration as you would in any iOS or Android project.

The challenge is getting Dart code to also be aware of the flavor, and the blog post provides no good solution for this. It suggests the standard method of using different entry points can be used, but the correct entry point must be matched to the correct flavor manually by the person invoking the app.

Daniel Brotherston
  • 1,954
  • 4
  • 18
  • 28
0

Specifically to Firebase env config you can use this article and this article from CodeMagic which explains how you can set up plist files with build env variables.

If you need to have a different set of values inside your Dart code, like an option you can use this package. It allows to generate Dart class config file from console command params.

Update 12/05/2020

Since Flutter 1.17 you can actually use compile-time variables with --dart-define argument in flutter run and flutter build commands

Here is an article that describes how to specify and use them.

tatsuDn
  • 2,019
  • 1
  • 9
  • 15
0

With the release of Flutter for Web to the stable channel, I put together instructions for targeting multiple firebase projects (e.g. dev, staging, prod) from multiple build platforms (i.e. iOS, Android, and Web).

YEG
  • 473
  • 4
  • 12
0

Late to the party, but for other people in the future. Please read if you are using Firebase and --dart-define because I just spent all day figuring this out.

So the official docs say to use 'source' in your firebase.json file. https://firebase.google.com/docs/hosting/frameworks/flutter What isn't clear is that when you have source in the config, it will build the flutter app when you run firebase deploy. That clears out any build parameters you sent in previously, even if you just built with --dart-define parameters.

The solution is to change your firebase.conf file to something like this:

{
  "hosting": {
    "public": "build/web",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "frameworksBackend": {
      "region": "us-central1"
    },
    "rewrites": [ {
   "source": "**",
   "destination": "/index.html"
} ]
  }
}

Then build your app

flutter build --dart-define=envFileName=local.env

Then deploy

firebase deploy