invertase / flutterfire_cli

A CLI to help with using FlutterFire in your Flutter applications.
Apache License 2.0
169 stars 47 forks source link

Support for multiple scheme dev, staging, prod #14

Closed ghensto closed 3 months ago

drklrd56 commented 1 year ago

I wrote a script that takes care of the firebase config for me. I hope this can be of some help. NOTE: I am using very_google_cli for flutter to create the flutter project with flavors

download the script.dart file and copy it to your project dir.

Requirements:

  1. Run dart pub add args in your project dir.
  2. Install firebase CLI tools through npm using the command npm install -g firebase-tools. If you don't have node installed on your system please install it first.
  3. Run this command dart pub global activate flutterfire_cli.

Steps:

  1. If you have firebase CLI installed run firebase logout. We must logout from firebase in order for this process to work.
  2. Login to firebase using firebase login. Don't use firebase login:ci, something the token is not registered using this method.
  3. While standing in the project directory(./project/), and depending on the flavor for which you want to generate the firebase config run one of the following commands:
    dart run script.dart development
    dart run script.dart staging
    dart run script.dart production

The script will take care of generating firebase configs and copying them to their desired locations.

FOR IOS:

add a build phase and copy this IOS BUILD PHASE SCRIPT from this link and save it

This script will copy over the plist file and id.json file on app build.

screenshot

StephenBanz commented 1 year ago

@drklrd56 Thanks for the script. it worked with android with a little bit of tuning. But the IOS build phase script didn't.

I had to change the script into the below one for it to work * I found it in one of the blogs Edit: it was from here https://gist.github.com/animeshjain/b7f754adee0a0a5ff1c41d698e6c6fb5#file-firebase-sh

environment="default"

# Regex to extract the scheme name from the Build Configuration
# We have named our Build Configurations as Debug-dev, Debug-prod etc.
# Here, dev and prod are the scheme names. This kind of naming is required by Flutter for flavors to work.
# We are using the $CONFIGURATION variable available in the XCode build environment to extract 
# the environment (or flavor)
# For eg.
# If CONFIGURATION="Debug-prod", then environment will get set to "prod".
if [[ $CONFIGURATION =~ -([^-]*)$ ]]; then
environment=${BASH_REMATCH[1]}
fi

echo $environment

# Name and path of the resource we're copying
GOOGLESERVICE_INFO_PLIST=GoogleService-Info.plist
GOOGLESERVICE_INFO_FILE=${PROJECT_DIR}/config/${environment}/${GOOGLESERVICE_INFO_PLIST}

# Make sure GoogleService-Info.plist exists
echo "Looking for ${GOOGLESERVICE_INFO_PLIST} in ${GOOGLESERVICE_INFO_FILE}"
if [ ! -f $GOOGLESERVICE_INFO_FILE ]
then
echo "No GoogleService-Info.plist found. Please ensure it's in the proper directory."
exit 1
fi

# Get a reference to the destination location for the GoogleService-Info.plist
# This is the default location where Firebase init code expects to find GoogleServices-Info.plist file
PLIST_DESTINATION=${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app
echo "Will copy ${GOOGLESERVICE_INFO_PLIST} to final destination: ${PLIST_DESTINATION}"

# Copy over the prod GoogleService-Info.plist for Release builds
cp "${GOOGLESERVICE_INFO_FILE}" "${PLIST_DESTINATION}"
russellwheatley commented 1 year ago

@StephenBanz

You need to use the latest dev release 😄. Run:

 dart pub global activate flutterfire_cli 0.3.0-dev.15 --overwrite
russellwheatley commented 1 year ago

@russellwheatley

You wouldn't be able run any FFCLI commands without it being installed if I understood your question correctly. (e.g. flutterfire configure). If you require FFCLI to run on your CI, it will have to be installed.

What command will copy ios/Firebase/development/GoogleService-Info.plist to ios/Runner/Info.plist folder. We have staging and production builds in Codemagic. Do we need to install FFCLI in Codemagic for copy script to work?

@asaarnak - thanks for the report on the firebase.json issue. I've just cut another dev release with a fix. Please run:

 dart pub global activate flutterfire_cli 0.3.0-dev.16 --overwrite
asaarnak commented 1 year ago
  1. Tested that firebase.json is now updated when re-running flutterfire configure.
  2. Does the bundle-service-file need firebase login? With flutterfire_cli 0.3.0-dev.14 the firebase login wasn't required.
  3. The shellScript in project.pbxproj contains absolute path. Could this be converted to relative path?
cuongHuuk commented 1 year ago

running flutterfire_cli 0.3.0-dev.16, it keep asking The file name must be "GoogleService-Info.plist" if you're bundling with your iOS target or build configuration. Do you want to change filename to "GoogleService-Info.plist"?. is there an command line option to chose yes please?

russellwheatley commented 1 year ago

The only time you can rename the file to something else on the CLI is if you're doing a simple write without any configuration (i.e. target or build configuration). It simply won't work if you have a different name for the file (it won't be recognised by Firebase iOS SDK when you bundle it with the app).

To be honest, it might be worth removing the ability to rename the file, and simply checking the filename matches GoogleService-Info.plist.

If the user makes the CLI choice to simply write the file and use their own service file bundling strategy, they're still going to have to name the file GoogleService-Info.plist. So it doesn't make sense that the file name should be anything but GoogleService-Info.plist 🤔.

I think I will change this in another dev release.

russellwheatley commented 1 year ago

@asaarnak

  1. Tested that firebase.json is now updated when re-running flutterfire configure.
  2. Does the bundle-service-file need firebase login? With flutterfire_cli 0.3.0-dev.14 the firebase login wasn't required.
  3. The shellScript in project.pbxproj contains absolute path. Could this be converted to relative path?

On point 1, thanks for testing 🚀.

On point 2, I really don't think that is down to the FFCLI changes, we're doing nothing different that would constitute a firebase login.

On point 3, I think I will create a bash script that will get the paths on the fly without any need for relative/absolute paths. I think this is possible. If so, it will be in a future dev release.

EArminjon commented 1 year ago

Is it normal that the firebase.json file is responsible of the GoogleService-Info.plist file selection ? I've many flavors, if I didn't run flutterfire configure before running one of them, the firebase.json file is not reloaded and the app took the wrong GoogleService-Info..plist...

What can i do to avoid that ?

I created an issue : https://github.com/invertase/flutterfire_cli/issues/158

I use :

 dart pub global activate flutterfire_cli 0.3.0-dev.16 --overwrite
russellwheatley commented 1 year ago

@EArminjon My initial reaction is that you've associated the service file with a target. Do you have one or multiple targets? If you only have the default Runner target then it is always going to use the service file for the Runner target.

You should use "build configurations". Let me know how that goes. Thanks

EArminjon commented 1 year ago

@EArminjon My initial reaction is that you've associated the service file with a target. Do you have one or multiple targets? If you only have the default Runner target then it is always going to use the service file for the Runner target.

You should use "build configurations". Let me know how that goes. Thanks

I've 4 Targets : Runner, Notifications, Watch, Watch Extension. I've 10 schemes : clienta, clientb, clientc,clientd etc.

I override my Targets properties with the current scheme.

russellwheatley commented 1 year ago

I override my Targets properties with the current scheme.

Not quite sure what you mean by this. The CLI will bundle that service file with the target you select via command prompt/command line argument. It will be bundled with whatever target you choose to build.

EArminjon commented 1 year ago

I override my Targets properties with the current scheme.

Not quite sure what you mean by this. The CLI will bundle that service file with the target you select via command prompt/command line argument. It will be bundled with whatever target you choose to build.

What if we have an unique Target but several scheme (build-configuration) ? Each scheme is a different app. The firebase.json issue block my ci :/

Edit : as i run flutterfire configure one time with target property, conf flag didn't work as expected. Once i revert the first run, conf flag work as expect. I'm able to configure well my flavors. My issue is fixed.

mxknt commented 1 year ago

Hey @stact, you will have to run the command for each environment you intend to use. VGV CLI creates an iOS app with 9 different build configurations. Choose the ones you want (presumably you don't need 9 different build configurations 😅) to use and run the command for each one.

@russellwheatley I was wondering if you could clarify this a little more -- I'm in the same boat, trying to add firebase to a project built w/ the vgv cli. It seems reasonable to me that you might want to have firebase work in all 9 build configurations, Debug/Profile/Release each for the dev/staging/prod flavors.

Assuming I do want to run flutterfire_configure 9 times, would each one need to specify a different GoogleService-Info.plist file via --ios-out? Or would I just run the command 3 times for each flavor, with

...
--ios-out=/ios/Firebase/development/GoogleService-Info.plist \
--ios-build-config=Debug-development

...
--ios-out=/ios/Firebase/development/GoogleService-Info.plist \
--ios-build-config=Profile-development

...
--ios-out=/ios/Firebase/development/GoogleService-Info.plist \
--ios-build-config=Release-development

etc.

With the examples I've seen here, it's not clear to me if that would work (I will try myself in the morning). I don't have a clear understanding of the platform specific build systems, so any info would be appreciated. Thanks!

russellwheatley commented 1 year ago

Hey @stact, you will have to run the command for each environment you intend to use. VGV CLI creates an iOS app with 9 different build configurations. Choose the ones you want (presumably you don't need 9 different build configurations 😅) to use and run the command for each one.

@russellwheatley I was wondering if you could clarify this a little more -- I'm in the same boat, trying to add firebase to a project built w/ the vgv cli. It seems reasonable to me that you might want to have firebase work in all 9 build configurations, Debug/Profile/Release each for the dev/staging/prod flavors.

Assuming I do want to run flutterfire_configure 9 times, would each one need to specify a different GoogleService-Info.plist file via --ios-out? Or would I just run the command 3 times for each flavor, with

...
--ios-out=/ios/Firebase/development/GoogleService-Info.plist \
--ios-build-config=Debug-development

...
--ios-out=/ios/Firebase/development/GoogleService-Info.plist \
--ios-build-config=Profile-development

...
--ios-out=/ios/Firebase/development/GoogleService-Info.plist \
--ios-build-config=Release-development

etc.

With the examples I've seen here, it's not clear to me if that would work (I will try myself in the morning). I don't have a clear understanding of the platform specific build systems, so any info would be appreciated. Thanks!

Yes, you would have to run the command 9 times. Once for each build configuration. The firebase.json created at the root of the project contains the values for each build configuration required at build time for finding your service file to bundle and values required for uploading the debug symbols for Crashlytics.

EArminjon commented 1 year ago

Hey @stact, you will have to run the command for each environment you intend to use. VGV CLI creates an iOS app with 9 different build configurations. Choose the ones you want (presumably you don't need 9 different build configurations 😅) to use and run the command for each one.

@russellwheatley I was wondering if you could clarify this a little more -- I'm in the same boat, trying to add firebase to a project built w/ the vgv cli. It seems reasonable to me that you might want to have firebase work in all 9 build configurations, Debug/Profile/Release each for the dev/staging/prod flavors.

Assuming I do want to run flutterfire_configure 9 times, would each one need to specify a different GoogleService-Info.plist file via --ios-out? Or would I just run the command 3 times for each flavor, with

...
--ios-out=/ios/Firebase/development/GoogleService-Info.plist \
--ios-build-config=Debug-development

...
--ios-out=/ios/Firebase/development/GoogleService-Info.plist \
--ios-build-config=Profile-development

...
--ios-out=/ios/Firebase/development/GoogleService-Info.plist \
--ios-build-config=Release-development

etc.

With the examples I've seen here, it's not clear to me if that would work (I will try myself in the morning). I don't have a clear understanding of the platform specific build systems, so any info would be appreciated. Thanks!

You can use my super script to avoid do it 3 times per flavors. It will do it for you :

firebase.sh

 #!/bin/sh

if [ $# -ne 4 ]; then
  echo "Need 4 arguments: firebaseProjectID, configurationName, iOSBundleId, androidPackageName"
  exit 1
fi

project=$1
configuration=$2
iosBundleId=$3
androidPackageName=$4

for prefix in "Debug" "Release" "Profile"; do
  echo 'yes' | flutterfire configure \
    --project="$project" \
    --out=lib/entrypoints/"$configuration"/firebase_options.dart \
    --android-out=/android/app/src/"$configuration"/google-services.json \
    --ios-bundle-id="$iosBundleId" \
    --android-package-name="$androidPackageName" \
    --ios-out=/ios/Firebase/"$configuration"/GoogleService-Info.plist \
    --ios-build-config="$prefix"-"$configuration" \
    --yes
done

Usage:

 ./firebase.sh firebaseProjectID flavorName iOSBundleId androidPackageName 
mxknt commented 1 year ago

Yes, you would have to run the command 9 times. Once for each build configuration. The firebase.json created at the root of the project contains the values for each build configuration required at build time for finding your service file to bundle and values required for uploading the debug symbols for Crashlytics.

Got it, thanks for clarifying!

@EArminjon thanks you! Very helpful

JaidynBluesky commented 1 year ago

@EArminjon

This is super helpful, thanks. However, is there a option to prevent it from adding the Crashlytics build step on iOS?

EArminjon commented 1 year ago

@EArminjon

This is super helpful, thanks. However, is there a option to prevent it from adding the Crashlytics build step on iOS?

With the echo, put no instead of yes. Note that, this will disable crashlytics steps inside the firebase.json too.

bac-huuk commented 1 year ago

flutterfire_cli: ^0.3.0-dev.16 Build phases:

Current: PATH=${PATH}:/Applications/flutter/bin:/Users/xxx/.pub-cache/bin Expect(MacOS): PATH=${PATH}:$FLUTTER_ROOT/bin:$HOME/.pub-cache/bin

cuongHuuk commented 1 year ago

@russellwheatley

russellwheatley commented 1 year ago

flutterfire_cli: ^0.3.0-dev.16 Build phases:

  • FlutterFire: "flutterfire upload-crashlytics-symbols"
  • FlutterFire: "flutterfire bundle-service-file" -> using absolute path -> there will be problems when using it on another device

Current: PATH=${PATH}:/Applications/flutter/bin:/Users/xxx/.pub-cache/bin Expect(MacOS): PATH=${PATH}:$FLUTTER_ROOT/bin:$HOME/.pub-cache/bin

@bac-huuk - awesome, that should work I think, I'll get this updated as part of the changes I'm currently making 👍

russellwheatley commented 1 year ago

Hey folks, I thought I'd get a quick temperature check on iOS/macOS configuration.

Is it useful making targets (i.e. --ios-target or --macos-target flags) configurable? It's quite a bit of work and adds a lot more complexity that might not be necessary if folks aren't using it.

I suspect the majority of people are going to build apps using build configurations (i.e. --ios-build-config or --macos-build-config flags). I was thinking of removing target configuration, but we will keep it if it is popular and being used.

I've created a survey monkey with a single question to find out if it is being used, and the results will determine whether we keep it. Please vote here: https://www.surveymonkey.co.uk/r/MVYWR78

Thanks!

feinstein commented 1 year ago

Sorry, can you explain the difference? When we would use one or the other?

EArminjon commented 1 year ago

Little feedback, some developpers create flavors using multiple targets instead of multiple build configurations. I think it could be great to keep this option for flexibility.

Btw, is it possible or allowed to select a target a and a specific build configuration? Actually, if I'm not wrong, the script only alllow target or only build configuration but didn't allow to mix them. This could be also great to increase flexibility of this tool...

But yep, it increase complexity.

russellwheatley commented 1 year ago

@feinstein

Sorry, can you explain the difference? When we would use one or the other?

target - a standard Flutter app (flutter create some_app) created has a Runner target only. It does not come with multiple targets, you would have to set them up if you wanted different targets for different environments (e.g. development, staging, production). build configuration - a standard Flutter app comes with three different build configurations set up: Debug, Profile & Release. You can see the build configurations by opening Xcode and editing the schemes:

Screenshot 2023-03-29 at 10 23 35

The VGV CLI actually creates 9 different build configurations on your Xcode project, and one target. I believe most developers will go down the road of using build configurations hence why I think it might not be worth the effort for targets.

russellwheatley commented 1 year ago

Little feedback, some developpers create flavors using multiple targets instead of multiple build configurations. I think it could be great to keep this option for flexibility.

Btw, is it possible or allowed to select a target a and a specific build configuration? Actually, if I'm not wrong, the script only alllow target or only build configuration but didn't allow to mix them. This could be also great to increase flexibility of this tool...

But yep, it increase complexity.

A build configuration is ultimately tied to a target, it wouldn't be possible for the FF CLI to figure out which service file to use when running the application. I don't recommend mixing them.

feinstein commented 1 year ago

Thank you for the explanation. AFAIK Flutter can only work with build configurations, the Flutter tool only accepts a target named Runner.

My app has lots of different build configurations, since it's a white label app, so we need to combine the white label with the environment, and their combination become the build configurations.

maRci002 commented 1 year ago

I think build configurations are more than enough since offical Creating flavors for Flutter creates only build configurations.

Flavors (known as build configurations in iOS), allow you (the developer) to create separate environments for your app using the same code base.

https://docs.flutter.dev/deployment/flavors#creating-flavors-in-ios

cedvdb commented 1 year ago

Is the ios build phase script still mandatory to move google service info plist into the correct directory ?

I'm having Build input file cannot be found: '/app/ios/Runner/GoogleService-Info.plist'. Did you forget to declare this file as an output of a script phase or custom build rule which produces it?

While the file generated have been put into /ios/dev/GoogleService-Info.plist,/ios/staging/GoogleService-Info.plist, ...

Doesn't fibase.json handle the linking behind the scene ?

davidnwaneri commented 1 year ago

I'm just thinking out loud - shouldn't this issue be renamed to something that relates to both the Android and iOS platforms, to give it more meaning as it actually relates to not just iOS.

creativecreatorormaybenot commented 1 year ago

@davidnwaneri it only relates to iOS. Android does not have build configurations and the multi-environment setup for Android has not changed.

erf commented 1 year ago

Sorry if a bit off topic, but i support multiple environments now quite easliy, without using flavors / multiple schemes, by using --dart-define-from-file, given an config_{my_env}.json file, and configuring this as part of my vscode launch.json. In the case of GoogleService-Info.plist and it's Android counterpart google-services.json, i use a vscode preLaunchTask to call a bash script which copies the correct Firebase config file to it's respective directory.

This inspired me to write an Medium article.

petrnymsa commented 1 year ago

Sorry if a bit off topic, but i support multiple environments now quite easliy, without using flavors / multiple schemes, by using --dart-define-from-file, given an config_{my_env}.json file, and configuring this as part of my vscode launch.json. In the case of GoogleService-Info.plist and it's Android counterpart google-services.json, i use a vscode preLaunchTask to call a bash script which copies the correct Firebase config file to it's respective directory.

This inspired me to write an Medium article.

This is nice for some basic application, but how you want to support things like custom app icons, applicationIdSuffix, custom label per flavor etc? That is, any config on native side of application without using flavors / multiple schemes?

erf commented 1 year ago

This is nice for some basic application, but how you want to support things like custom app icons, applicationIdSuffix, custom label per flavor etc? That is, any config on native side of application without using flavors / multiple schemes?

You would pass in those things as arguments via the config{_prod|dev}.json you pass in via --dart-define-from-file. You are able to access those variables natively (as mentioned in the article), on Android in build.gradle via project.getProperty, from there you can set various other properties (like applicationIdSuffix). And on iOS via Generated.xcconfig. E.g. you could store the app icons using different file names for different builds and pass the name you'd want to use for the current build as an argument via config.json or you could copy the file want to use as a preLaunchTask. I hope that give you some ideas. I'd rather not discuss this further here as to not make too much noise.

cedvdb commented 1 year ago

@erf

Thanks, the idea of using vs code to change the GoogleService-Info.plist, worked in my case while the build phase scripts with the latest version of the cli somehow always had issues. Note that I'm using flavors too.

What worked for me for ios and android:

  1. Create flavors with flutter_flavorizr
  2. Go back to stable version of the flutterfire cli
  3. run flutterfire configure for dev
flutterfire configure --project myproject-dev --platforms='web,ios,android' --out ../infrastructure/lib/firebase/configs/firebase_options_dev.dart --ios-bundle-id com.myproject.app.dev --android-package-name com.myproject.app.dev
  1. Move google-service.json in the correct flavor directory in android
  2. Move GoogleService-Info.plist and firebase_app_id_file.json under ios/Configs/dev/
  3. Repeat step 3 to 5 for staging and prod
  4. add tasks.json in .vscode
{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "copy-config-dev-task",
      "type": "shell",
      "command": "cp app/ios/Configs/dev/firebase_app_id_file.json app/ios/firebase_app_id_file.json && cp app/ios/Configs/dev/GoogleService-Info.plist app/ios/Runner/GoogleService-Info.plist"
    },
    {
      "label": "copy-config-staging-task",
      "type": "shell",
      "command": "cp app/ios/Configs/staging/firebase_app_id_file.json app/ios/firebase_app_id_file.json && cp app/ios/Configs/staging/GoogleService-Info.plist app/ios/Runner/GoogleService-Info.plist"
    },
  1. Add launcher preLaunchTask

  "configurations": [
    {
      "name": "myproject dev",
      "request": "launch",
      "type": "dart",
      "program": "app/lib/main_dev.dart",
      "preLaunchTask": "copy-config-dev-task",
      "args": [
        "--flavor",
        "dev",
      ]
    },
  ]
SherpaMiguel commented 1 year ago

Thanks for your comments. For me firebase_app_id_file.json files are not being generated. I'm using @EArminjon super script but looks like something is wrong in 0.3.0-dev.16 version.

My project has 3 flavors and I was copying GoogleService-Info.plist with the Build Phase script on XCode. Is this script still necessary?

Problems came when I added analytics and crashlytics to my 3 environments.

In fact I don't know if I really need firebase_app_id_file.json files. I would appreciate a explanation of what this file is thought to. Looks like it duplicates GoogleService-Info.plist info.

Don't like the idea of changing GoogleService-Info.plist with VS Code tasks. It would work on our dev environment, but integrating the project with automated deployment services would be a headache.

chrisfraser commented 1 year ago

I have tested 0.3.0-dev.16 by running for each of the 9 build/flavor combos on latest flutter. This is using a new project created with very_good create flutter_app

Flutter 3.10.0 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 84a1e904f4 (6 days ago) • 2023-05-09 07:41:44 -0700
Engine • revision d44b5a94c9
Tools • Dart 3.0.0 • DevTools 2.23.1
...
--ios-out=/ios/Firebase/development/GoogleService-Info.plist \
--ios-build-config=Debug-development

...
--ios-out=/ios/Firebase/development/GoogleService-Info.plist \
--ios-build-config=Profile-development

...
--ios-out=/ios/Firebase/development/GoogleService-Info.plist \
--ios-build-config=Release-development

I consistently get the following error:

Unable to find a target named `RunnerTests` in project `Runner.xcodeproj`, did find `Runner`.
thuytrinh commented 1 year ago

I've tried 0.3.0-dev.16 and called the following command on my project my_app:

flutterfire configure \
  --account=abc@xyz.de \
  --project="my-firebase-dev" \
  --platforms="ios,android" \
  --ios-build-config=Debug-dev \
  --ios-out=ios/config/dev/GoogleService-Info.plist \
  --android-out=android/app/src/dev/google-services.json \
  --ios-bundle-id="com.company.myapp.dev" \
  --android-package-name="com.company.myapp.dev" \
  --debug-symbols-ios \
  --overwrite-firebase-options \
  --yes

There are still some issues:

  1. The generated google-services.json was created in a wrong path, the first folder in the hierarchy was my_appandroid instead of android. So it generated a new folder my_appandroid. There could be something wrong with the path logic in the CLI. I could fix it by declaring --android-out=/android/app/src/dev/google-services.json with a / in front of android.
  2. The CLI didn't overwrite the Google-Service plist as I expected because in this case, I wanted to register new apps with Firebase. Since you offered a --[no-]overwrite-firebase-options, wondering whether you should also offer an option to overwrite the plist file? Or was there a bug with the CLI? Right now, I worked around by deleting the plist file before running the configure command.
  3. The generated shellScript for both flutterfire bundle-service-file action & flutterfire upload-crashlytics-symbol action still got some user-dependent path. For example:
    #!/bin/bash
    PATH=${PATH}:/Users/thuy/dev/flutter/bin:/Users/thuy/.pub-cache/bin
    flutterfire bundle-service-file --plist-destination=${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app --build-configuration=${CONFIGURATION} --platform=ios --apple-project-path=${SRCROOT}

    The Users/thuy/dev/flutter/bin:/Users/thuy/.pub-cache/bin is rather my local path. This is a problem if working with a team project. Is it necessary to include PATH=${PATH}:/Users/thuy/dev/flutter/bin:/Users/thuy/.pub-cache/bin in the shell script? If one uses flutterfire, should it be already available in the local path as well as CI path, right?

Nonetheless, good to see that the CLI is getting more flexible and useful. Hope this helps.

thuytrinh commented 1 year ago
  1. The bundle-service-file script seems very broken:
Unhandled exception:
type 'Null' is not a subtype of type 'Map<dynamic, dynamic>' in type cast
#0      appleConfigFromFirebaseJson (package:flutterfire_cli/src/common/utils.dart:253:46)
<asynchronous suspension>
#1      BundleServiceFile.run (package:flutterfire_cli/src/commands/bundle_service_file.dart:86:9)
<asynchronous suspension>
#2      CommandRunner.runCommand (package:args/command_runner.dart:212:13)
<asynchronous suspension>
#3      main (file:///Users/thuy/.pub-cache/hosted/pub.dev/flutterfire_cli-0.3.0-dev.16/bin/flutterfire.dart:63:5)
<asynchronous suspension>
Command PhaseScriptExecution failed with a nonzero exit code

Command PhaseScriptExecution failed with a nonzero exit code

My project has a very typical multi-flavor setup with 2 schemes: dev and pro and 4 build configurations: Debug-dev, Profile-dev, Release-dev, Debug-pro, Profile-pro, and Release-pro.

russellwheatley commented 1 year ago

Hey @thuytrinh, thanks for the feedback! There's been a lot of changes to the codebase since the last release: https://github.com/invertase/flutterfire_cli/pulls?q=is%3Apr+sort%3Aupdated-desc+is%3Amerged

I'll double check your observations before making another release. Thanks 👍

russellwheatley commented 1 year ago

Thanks for your comments. For me firebase_app_id_file.json files are not being generated. I'm using @EArminjon super script but looks like something is wrong in 0.3.0-dev.16 version.

My project has 3 flavors and I was copying GoogleService-Info.plist with the Build Phase script on XCode. Is this script still necessary?

Problems came when I added analytics and crashlytics to my 3 environments.

In fact I don't know if I really need firebase_app_id_file.json files. I would appreciate a explanation of what this file is thought to. Looks like it duplicates GoogleService-Info.plist info.

Don't like the idea of changing GoogleService-Info.plist with VS Code tasks. It would work on our dev environment, but integrating the project with automated deployment services would be a headache.

@gelas7 - the pending dev release doesn't generate firebase_app_id_file.json file anymore, a script is created in the Run Phase Build Script's that will upload the symbols without this file being written to your codebase.

russellwheatley commented 1 year ago

I've tried 0.3.0-dev.16 and called the following command on my project my_app:

flutterfire configure \
  --account=abc@xyz.de \
  --project="my-firebase-dev" \
  --platforms="ios,android" \
  --ios-build-config=Debug-dev \
  --ios-out=ios/config/dev/GoogleService-Info.plist \
  --android-out=android/app/src/dev/google-services.json \
  --ios-bundle-id="com.company.myapp.dev" \
  --android-package-name="com.company.myapp.dev" \
  --debug-symbols-ios \
  --overwrite-firebase-options \
  --yes

There are still some issues:

  1. The generated google-services.json was created in a wrong path, the first folder in the hierarchy was my_appandroid instead of android. So it generated a new folder my_appandroid. There could be something wrong with the path logic in the CLI. I could fix it by declaring --android-out=/android/app/src/dev/google-services.json with a / in front of android.
  2. The CLI didn't overwrite the Google-Service plist as I expected because in this case, I wanted to register new apps with Firebase. Since you offered a --[no-]overwrite-firebase-options, wondering whether you should also offer an option to overwrite the plist file? Or was there a bug with the CLI? Right now, I worked around by deleting the plist file before running the configure command.
  3. The generated shellScript for both flutterfire bundle-service-file action & flutterfire upload-crashlytics-symbol action still got some user-dependent path. For example:
#!/bin/bash
PATH=${PATH}:/Users/thuy/dev/flutter/bin:/Users/thuy/.pub-cache/bin
flutterfire bundle-service-file --plist-destination=${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app --build-configuration=${CONFIGURATION} --platform=ios --apple-project-path=${SRCROOT}

The Users/thuy/dev/flutter/bin:/Users/thuy/.pub-cache/bin is rather my local path. This is a problem if working with a team project. Is it necessary to include PATH=${PATH}:/Users/thuy/dev/flutter/bin:/Users/thuy/.pub-cache/bin in the shell script? If one uses flutterfire, should it be already available in the local path as well as CI path, right?

Nonetheless, good to see that the CLI is getting more flexible and useful. Hope this helps.

I checked all three issues you mentioned. None of them are an issue anymore:

  1. Fixed in the refactor PR: https://github.com/invertase/flutterfire_cli/pull/167
  2. Fixed in this PR: https://github.com/invertase/flutterfire_cli/pull/174
  3. Fixed in this PR: https://github.com/invertase/flutterfire_cli/pull/175

I am hoping to get another dev release out soon, just going through review process at the moment 👍

russellwheatley commented 1 year ago
  1. The bundle-service-file script seems very broken:
Unhandled exception:
type 'Null' is not a subtype of type 'Map<dynamic, dynamic>' in type cast
#0      appleConfigFromFirebaseJson (package:flutterfire_cli/src/common/utils.dart:253:46)
<asynchronous suspension>
#1      BundleServiceFile.run (package:flutterfire_cli/src/commands/bundle_service_file.dart:86:9)
<asynchronous suspension>
#2      CommandRunner.runCommand (package:args/command_runner.dart:212:13)
<asynchronous suspension>
#3      main (file:///Users/thuy/.pub-cache/hosted/pub.dev/flutterfire_cli-0.3.0-dev.16/bin/flutterfire.dart:63:5)
<asynchronous suspension>
Command PhaseScriptExecution failed with a nonzero exit code

Command PhaseScriptExecution failed with a nonzero exit code

My project has a very typical multi-flavor setup with 2 schemes: dev and pro and 4 build configurations: Debug-dev, Profile-dev, Release-dev, Debug-pro, Profile-pro, and Release-pro.

I haven't come across this yet, I wonder if you tried to edit the "firebase.json" file manually? If so, you shouldn't 😄

russellwheatley commented 1 year ago

I have tested 0.3.0-dev.16 by running for each of the 9 build/flavor combos on latest flutter. This is using a new project created with very_good create flutter_app

Flutter 3.10.0 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 84a1e904f4 (6 days ago) • 2023-05-09 07:41:44 -0700
Engine • revision d44b5a94c9
Tools • Dart 3.0.0 • DevTools 2.23.1
...
--ios-out=/ios/Firebase/development/GoogleService-Info.plist \
--ios-build-config=Debug-development

...
--ios-out=/ios/Firebase/development/GoogleService-Info.plist \
--ios-build-config=Profile-development

...
--ios-out=/ios/Firebase/development/GoogleService-Info.plist \
--ios-build-config=Release-development

I consistently get the following error:

Unable to find a target named `RunnerTests` in project `Runner.xcodeproj`, did find `Runner`.

This is bizarre, this feedback is from the CLI

> Unable to find a target named `RunnerTests` in project `Runner.xcodeproj`, did find `Runner`.

It is saying you selected RunnerTests as the target, but it could only find Runner as the target. show me the command you're running, please?

michi88 commented 1 year ago

I have tested 0.3.0-dev.16 by running for each of the 9 build/flavor combos on latest flutter. This is using a new project created with very_good create flutter_app

Flutter 3.10.0 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 84a1e904f4 (6 days ago) • 2023-05-09 07:41:44 -0700
Engine • revision d44b5a94c9
Tools • Dart 3.0.0 • DevTools 2.23.1
...
--ios-out=/ios/Firebase/development/GoogleService-Info.plist \
--ios-build-config=Debug-development

...
--ios-out=/ios/Firebase/development/GoogleService-Info.plist \
--ios-build-config=Profile-development

...
--ios-out=/ios/Firebase/development/GoogleService-Info.plist \
--ios-build-config=Release-development

I consistently get the following error:

Unable to find a target named `RunnerTests` in project `Runner.xcodeproj`, did find `Runner`.

This is bizarre, this feedback is from the CLI

> Unable to find a target named `RunnerTests` in project `Runner.xcodeproj`, did find `Runner`.

It is saying you selected RunnerTests as the target, but it could only find Runner as the target. show me the command you're running, please?

Have the same issue on an empty project, I think it happens on the pod install step. Commented out in Podfile for now:

...
  #target 'RunnerTests' do
    #  inherit! :search_paths
  #end
...

Not an experienced mobile / flutter dev so no idea what I'm doing yet. FYI.

EArminjon commented 1 year ago

I've tried 0.3.0-dev.16 and called the following command on my project my_app:

flutterfire configure \
  --account=abc@xyz.de \
  --project="my-firebase-dev" \
  --platforms="ios,android" \
  --ios-build-config=Debug-dev \
  --ios-out=ios/config/dev/GoogleService-Info.plist \
  --android-out=android/app/src/dev/google-services.json \
  --ios-bundle-id="com.company.myapp.dev" \
  --android-package-name="com.company.myapp.dev" \
  --debug-symbols-ios \
  --overwrite-firebase-options \
  --yes

There are still some issues:

  1. The generated google-services.json was created in a wrong path, the first folder in the hierarchy was my_appandroid instead of android. So it generated a new folder my_appandroid. There could be something wrong with the path logic in the CLI. I could fix it by declaring --android-out=/android/app/src/dev/google-services.json with a / in front of android.
  2. The CLI didn't overwrite the Google-Service plist as I expected because in this case, I wanted to register new apps with Firebase. Since you offered a --[no-]overwrite-firebase-options, wondering whether you should also offer an option to overwrite the plist file? Or was there a bug with the CLI? Right now, I worked around by deleting the plist file before running the configure command.
  3. The generated shellScript for both flutterfire bundle-service-file action & flutterfire upload-crashlytics-symbol action still got some user-dependent path. For example:
#!/bin/bash
PATH=${PATH}:/Users/thuy/dev/flutter/bin:/Users/thuy/.pub-cache/bin
flutterfire bundle-service-file --plist-destination=${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app --build-configuration=${CONFIGURATION} --platform=ios --apple-project-path=${SRCROOT}

The Users/thuy/dev/flutter/bin:/Users/thuy/.pub-cache/bin is rather my local path. This is a problem if working with a team project. Is it necessary to include PATH=${PATH}:/Users/thuy/dev/flutter/bin:/Users/thuy/.pub-cache/bin in the shell script? If one uses flutterfire, should it be already available in the local path as well as CI path, right? Nonetheless, good to see that the CLI is getting more flexible and useful. Hope this helps.

I checked all three issues you mentioned. None of them are an issue anymore:

  1. Fixed in the refactor PR: refactor: update implementation to make it more modular and easier to understand #167
  2. Fixed in this PR: feat: overwrite Apple service files if they exist already. #174
  3. Fixed in this PR: fix: remove absolute paths from run phase build script #175

I am hoping to get another dev release out soon, just going through review process at the moment 👍

Hi any update about the new release :) ? (working on team project, the issue about local path is important)

stact commented 1 year ago

As mentioned we don’t need 9 flavors to be set up

https://github.com/invertase/flutterfire_cli/issues/14#issuecomment-1423921383

Please also get additional details in whole conversation for how to check flavors https://github.com/invertase/flutterfire_cli/issues/14#issuecomment-1488254402

also be aware it’s in development not for prod purpose you can still configure and go live with manual configuration

hope it helps

russellwheatley commented 1 year ago

I will update the channel when the latest dev release is out @EArminjon. I'm hoping not too long but it is going through a review process as a lot of changes have occurred since the last release.

mavinis commented 1 year ago

So I come back to this thread every time I need to start a new project in Flutter hoping there's an official solution, but the recent comments got me a bit confused. Simple question:

As of July 2023, is FlutterFire Cli able to generate the right configuration for each platform, considering multiple Flavors associated with their respective Firebase projects, without neglecting that essential tools like Analytics and Crashlytics require unique google-services.json files in each environment?