【Flutter 3.19対応】Dart-define-from-fileを使って開発環境と本番環境を分ける
開発環境 | ステージング環境 | 本番環境 |
---|---|---|
はじめに
こんにちは、Flutterでのアプリ開発をメインとしている「Altive株式会社」の村松龍之介(@riscait)です!
Flutterにおいて、その環境分けの方法はいくつかありますが、今回は Dart-defines-from-file
を使用して実現する方法をご紹介します。
dart-define-from-file
のメリット
Flavor用のパッケージを使う場合等と比べて、ビルドコマンドがシンプルになることや、自動生成ファイルが少なく、取り回しがしやすいことが大きな利点です。
-
main.dart
を環境ごとに分ける必要がない - iOSの
scheme
やConfiguration
を作成する必要がない - パッケージの導入が不要(アイコン生成には使用します)
前提
- この記事では以下の3環境に分けていきます
(あくまで一例なので、数や名前は適宜変更してください)-
dev
: ローカルの開発環境 -
stg
: 本番環境に似せた環境を用意し、検証を行う環境 -
prod
: 実際に公開するアプリで使用する本番環境
-
- Flutter 3.7 以上を想定
- 当記事の手法はFlutter 3.7 以上で利用可能です。
- 対応OS
- ✅ Android
- ✅ iOS
- ✅ macOS
- ✅ Web
サンプルコード(リポジトリ)
- 環境分けを適用したアプリプロジェクトのサンプルはこちら↓
当記事で例として使用する環境分け情報
- アプリ名
- dev:
FAT dev
- stg:
FAT stg
- prod:
FAT
- dev:
- アプリID (Bundle ID, Package name)
- dev:
jp.co.altive.fat.dev
- stg:
jp.co.altive.fat.stg
- prod:
jp.co.altive.fat
- dev:
dev, stg環境の場合はアプリ名とアプリIDに、それぞれ環境名を足したもので表現したいと思います。
もちろん、「アプリ名の方は(dev)のように括弧で表現する」といったことも自由なので、適宜ご調整ください。
Firebaseを使用する場合
- Firebaseを使用している場合は、
flutterfire-cli
を使用したり、FirebaseのWebコンソールから環境数分のプロジェクトとアプリを作成して、iOS用のGoogleService-Info.plist
とgoogle-services.json
をダウンロードしておきましょう。
dart-define-from-fileを使う
それでは、 dart-define-from-file
を使った環境分けを行っていきましょう。
環境の数だけ定義をまとめたファイルを作成する(JSON or ENV)
まずは環境名や、環境ごとのアプリ名など、必要な項目を定義するファイルを作成しましょう👌
ファイルは、 .json
か .env
が使えます。
ファイルの配置場所とファイル名は自由です。
今回は例として dart_defines
ディレクトリを作成して dev.env
という名前で作成するとします。
flavor="dev"
appName="FAT dev"
appId="jp.co.altive.fat.dev"
googleReversedClientId="com.googleusercontent.apps.0123456789-xxxxxxxxxxxxxxxx"
同じように環境数分のファイルを作成しましょう。
flavor="stg"
appName="FAT stg"
appId="jp.co.altive.fat.stg"
googleReversedClientId="com.googleusercontent.apps.0123456789-xxxxxxxxxxxxxxxx"
flavor="prod"
appName="FAT"
appId="jp.co.altive.fat"
googleReversedClientId="com.googleusercontent.apps.0123456789-xxxxxxxxxxxxxxxx"
アプリビルド時にコマンドで環境を指定する
アプリ起動(run)やビルド(build)時に環境を分けるために、 --dart-define-from-file
というオプションを指定します。
下記の例では、 dev
(開発環境)を指定しています。
# アプリ起動コマンドの例
flutter run --dart-define-from-file=dart_defines/dev.env
# アプリビルドコマンドの例
flutter build ios --dart-define-from-file=dart_defines/dev.env
VS Code の設定例
VS Code では、 launch.json
で起動コマンドを編集できます。
すでにファイルがある場合は、既存ファイルを編集し、ない場合は .vscode
ディレクトリを作成し、 launch.json
を追加しましょう。
以下のように args
にて --dart-define-from-file
を指定可能です。
dev, stg, prod 3環境分用意した例です。
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug dev",
"request": "launch",
"type": "dart",
"flutterMode": "debug",
"args": [
"--dart-define-from-file=dart_defines/dev.env"
]
},
{
"name": "Debug stg",
"request": "launch",
"type": "dart",
"flutterMode": "debug",
"args": [
"--dart-define-from-file=dart_defines/stg.env"
]
},
{
"name": "Debug prod",
"request": "launch",
"type": "dart",
"flutterMode": "debug",
"args": [
"--dart-define-from-file=dart_defines/prod.env"
]
}
]
}
Android Studio の設定例
Add Configuration
または Edit Configurations
からFlutterの起動構成を設定しましょう。
詳しくは、Daigoさんが書いてくださった記事を参考にしてください👍
FlutterアプリでDart defineで設定した情報を取得する
起動/ビルドコマンドで指定した dart-define-from-file
がきちんと反映されているかも確認することができるので試しておきましょう。
env(またはjson)ファイル内で定義したプロパティは fromEnvironment
メソッドで個別に取得することが可能です👍
- 文字列:
String.fromEnvironment(name)
- 数値:
int.fromEnvironment(name)
- 真偽値:
bool.fromEnvironment(name)
// `--dart-define-from-file=dart_defines/dev.env` に定義した `flavor` プロパティを取得したい場合
const flavor = String.fromEnvironment('flavor');
print(flavor) // 'dev'
アプリIconを環境別に分ける
※ Icon画像を環境別に分けない場合は読み飛ばしてください。
環境別のアイコン画像をフォルダに配置します
※ 画像は適宜用意してください
assets/launcher_icon/icon-dev.png
assets/launcher_icon/icon-stg.png
assets/launcher_icon/icon-prod.png
flutter_launcher_iconsパッケージをインストール
flutter pub add flutter_launcher_icons --dev
もしくは pubspec.yaml に追記して pub get
します。
dev_dependencies:
flutter_launcher_icons: ^0.13.1 # インストール時点での最新版を推奨
Flavorごとの設定ファイルを作成
flutter_launcher_icons-dev.yaml
flutter_launcher_icons-stg.yaml
flutter_launcher_icons-prod.yaml
flutter_launcher_icons:
android: true
ios: true
image_path: "assets/launcher_icon/icon-dev.png"
アイコン画像の書き出し実行
dart run flutter_launcher_icons
✓ Successfully generated launcher icons for flavors
と表示されれば成功です。
iOSでは ios/Runner/Assets.xcassets/AppIcon-{flavor}.appiconset/
Androidでは android/app/src/{flavor}/mipmap**/ic_launcher.png
に出力されているはずです👍
Androidアプリに必要な対応
定義した Dart-define
を反映させるために build.gradle
と AndroidManifest.xml
ファイルを編集していきましょう。
build.gradle を編集して dart-define を受け取る
Dart-define をデコードして受け取ります。
// dart-define を入れる変数を宣言しています。
def dartDefines = [:];
if (project.hasProperty('dart-defines')) {
// カンマ区切りかつBase64でエンコードされている dart-defines をデコードして変数に格納します。
dartDefines = dartDefines + project.property('dart-defines')
.split(',')
.collectEntries { entry ->
def pair = new String(entry.decodeBase64(), 'UTF-8').split('=')
pair.length == 2 ? [(pair.first()): pair.last()] : [:]
}
}
defaultConfig
でアプリIDとアプリ名を設定
defaultConfig {
minSdkVersion flutter.minSdkVersion
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
+ applicationId "${dartDefines.appId}"
+ resValue "string", "app_name", "${dartDefines.appName}"
}
-
applicationId
でアプリ名を指定 -
resValue
を使用してアプリ名を指定
defaultConfigで設定したアプリ名を使用するようにする
android/app/src/main/AndroidManifest.xml
を編集して、 build.gradle
で設定したアプリ名を使用するようにします。
- android:label="flutter_app_template"
+ android:label="@string/app_name"
これで環境によってアプリ名が変わるようになりました。
アイコンを切り替えるためのタスクを追加する
flutter_launcher_icons
パッケージを使って環境ごとのアイコンを作成しておきます。
src/{flavor}/res
ディレクトリに複数の mipmap-xxx
ディレクトリがあり、 ic_launcher.png
が生成されています。
環境により、これらのアイコンを切り替えたいため、 build.gradle
に以下を追記します。
// android/app/build.gradle
task copySources(type: Copy) {
from "src/${dartDefines.flavor}/res"
into 'src/main/res'
}
tasks.whenTaskAdded { task ->
task.dependsOn copySources
}
ビルド時に環境ごとのディレクトリ内の res
を src/main/res
にコピーしています。
以前のandroid.sourceSets.mainで複数のフォルダをres.srcDirsに指定する方法
※ src/main/res
の中身を削除しても、 flutter create
を実行すると、再度 src/main/res
内にアイコンファイル等が生成されてしまい、起動時にファイルの重複エラーが発生してしまうため、こちらの方法は使わないことにしました。
android {
compileSdkVersion flutter.compileSdkVersion
sourceSets {
main {
java.srcDirs += 'src/main/kotlin'
res.srcDirs = ['src/main/res', "src/${dartDefines.flavor}/res"]
}
}
...
res.srcDirs
を指定し、 src/main/res
と src/{flavor}/res
をマージしています。
この時、この2つのディレクトリに同じファイルが存在するとエラーになるので、2箇所に同じファイルが存在しないようにしましょう。
@kurogoma4d さん、コメントありがとうございました!
Firebase対応 (Android)
android/app/src
に各環境(Flavor)と同名のディレクトリ(フォルダ)を作成。
-
android/app/src/dev/
,android/app/src/stg/
,android/app/src/prod/
各Firebaseプロジェクトに作ったAndroidアプリ用の google-services.json
をそれぞれのディレクトリに配置します。
android/app/build.gradle
に追記
環境別ディレクトリに配置した google-services.json
を android/app
にコピーするタスクを定義しています。
task selectGoogleServicesJson(type: Copy) {
from "src/${dartDefines.flavor}/google-services.json"
into './'
}
tasks.whenTaskAdded { task ->
if (task.name == 'processDebugGoogleServices' || task.name == 'processReleaseGoogleServices') {
task.dependsOn selectGoogleServicesJson
}
}
.gitignore
ファイルに google-services.json
を追加
android/app/google-services.json
は、ビルド時に生成されて環境ごとに上書きされるので、Git管理対象外にしましょう。
+ **/android/app/google-services.json
iOSアプリに必要な対応
Dart define を受け取る Pre Actionを追加
ビルド時に指定した --dart-define
をiOSで受け取るために、ビルド直前に実行されるスクリプトを追加する必要があります。
もちろん、スクリプトをXcode上から直接書き込んでも良いですが、
-
Runner.xcscheme
に改行がない状態で書き込まれるので差分が見にくい - コメント等で日本語を書くとエンコードされて読めない
というデメリットがあり、新規ファイルを作成して使うことで、好きなエディタ(VS Codeなど)のハイライト機能等を利用しながら編集できる利点もあります。
スクリプトファイル保存
ios/scripts/extract_dart_defines.sh
というパスとファイル名で以下の内容の sh
ファイルを保存します。
#!/bin/sh
# Dart defineを書き出すファイルパスを指定します。
# ここでは `Dart-Defines.xcconfig` というファイル名で作成することにします。
OUTPUT_FILE="${SRCROOT}/Flutter/Dart-Defines.xcconfig"
# Dart defineの中身を変更した時に古いプロパティが残らないように、初めにファイルを空にしています。
: > $OUTPUT_FILE
# この関数でDart defineをデコードします。
function decode_url() { echo "${*}" | base64 --decode; }
IFS=',' read -r -a define_items <<<"$DART_DEFINES"
for index in "${!define_items[@]}"
do
item=$(decode_url "${define_items[$index]}")
# Dartの定義にはFlutter側で自動定義された項目も含まれます。
# しかし、それらの定義を書き出してしまうとエラーによりビルドができなくなるので、
# flutterやFLUTTERで始まる項目は出力しないようにしています。
lowercase_item=$(echo "$item" | tr '[:upper:]' '[:lower:]')
if [[ $lowercase_item != flutter* ]]; then
echo "$item" >> "$OUTPUT_FILE"
fi
done
XcodeのBuild Pre-actions に作成したスクリプトを登録する
- Xcodeで、Product > Scheme > Edit Scheme (⌘ ⇧ <)を開きます
- XcodeのScheme (Runner) をクリックして
Edit scheme
-> Build を展開してPre-actions
を選択します - 「+」ボタンを押して「New Run Script Action」を選択します。
- 「Provide build settings from」は
Runner
を選択します。 - 先ほど保存したファイルのパスである
${SRCROOT}/scripts/extract_dart_defines.sh
を書き込みます。
スクリプトファイルに実行権限を与える
そのままビルドしてもスクリプトファイルが実行されません。
以下のコマンドで実行限限を与えておきましょう。
chmod 755 ios/scripts/extract_dart_defines.sh
Dart-Defines.xcconfig
をインポート
各種xcconfigファイルで 前項のスクリプトで生成される Dart-Defines.xcconfig
がDebug, Releaseビルド両方で使われるように、既存の *.xcconfig
ファイルでインクルードします。
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"
+ #include "Dart-Defines.xcconfig"
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
+ #include "Dart-Defines.xcconfig"
.gitignore
ファイルに Dart-Defines.xcconfig
を追加
Dart-Defines.xcconfig
は、ビルド時に生成され、環境により内容が上書きされるので、Git管理対象外にします。
+ **/ios/Flutter/Dart-Defines.xcconfig
アプリ表示名を環境によって変える
ios/Runner/Info.plist
を編集します。
アプリ名に使われる CFBundleDisplayName
と CFBundleName
にアプリ名を指定します。
<key>CFBundleName</key>
- <string>flutter_app_template</string>
+ <string>$(appName)</string>
+ <key>CFBundleDisplayName</key>
+ <string>$(appName)</string>
環境ごとに以下のようなアプリ名が表示されるようになりました👍
- dev:
FAT dev
- stg:
FAT stg
- prod:
FAT
Bundle IDを環境によって変える
ios/Runner.xcodeproj/project.pbxproj
を PRODUCT_BUNDLE_IDENTIFIER
で検索するか、
Xcode > Runner > TARGETS Runner > Build Settings の Product Bundle Identifier
を表示して、
$(appId)
に変更します。
Debug, Profile, Release すべてのBundle IDに $(appId) が設定されていることを確認してください。
- PRODUCT_BUNDLE_IDENTIFIER = "jp.co.altive.fat";
+ PRODUCT_BUNDLE_IDENTIFIER = "$(appId)";
これで、環境ごとにアプリのBundle IDが変わるようになりました👏
Appアイコンを環境によって変える
ios/Runner.xcodeproj/project.pbxproj
を ASSETCATALOG_COMPILER_APPICON_NAME
で検索するか、
Xcode > Runner > TARGETS Runner > Build Settings の Primary App Icon Set Name
を表示して、
AppIcon
と指定されている値を AppIcon-$(flavor)
に変更します。
忘れずに Debug, Profile, Release すべて共通の値になるようにしましょう。
# ios/runner.xcodeproj/project.pbxproj
- ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon";
+ ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-$(flavor)";
これで、環境ごとにアプリのアイコンが変わるようになりました👏
Firebase対応 (iOS)
Firebaseを使用していてかつ環境ごとにプロジェクトを分ける場合は、GoogleService-Info.plist
を環境ごとに使い分ける必要があります。
ios
ディレクトリに各環境(Flavor)と同名のディレクトリ(フォルダ)を作成。
-
ios/dev/
,ios/stg/
,ios/prod/
各Firebaseプロジェクトに作ったiOSアプリ用の GoogleService-Info.plist
をそれぞれのディレクトリに配置します。
Select GoogleService-Info.plist
ビルド時に、環境に対応した GoogleService-Info.plist
を使用できるようにするスクリプトを追加します。
-
Build phases
->New run script
を選択して新しいRun Script
を追加 - 名前をわかりやすいように
Select GoogleService-Info.plist
に変更 - スクリプトを記述
-
Output Files
に$(SRCROOT)/Runner/GoogleService-Info.plist
を追加 - 既存Scriptである
Copy Bundle Resources
より上に移動
\cp -f ${SRCROOT}/${flavor}/GoogleService-Info.plist ${SRCROOT}/Runner/GoogleService-Info.plist
.gitignore
ファイルに GoogleService-Info.plist
追加
ios/Runner/GoogleService-Info.plist
は、ビルド時に生成されて環境により内容が変わるので、Git管理対象外にします。
+ **/ios/Runner/GoogleService-Info.plist
macOS対応
macOSの対応は、ほとんどiOSと同じです。
ios
ディレクトリを macos
ディレクトリに読み替えて同じように実行してください。
一部、異なる点を以下の通りです。
- iOSの
Debug.xcconfig
は、macOSではFlutter-Debug.xcconfig
という名前です - iOSの
Release.xcconfig
は、macOSではFlutter-Release.xcconfig
という名前です
Flutterアプリを起動して、Flavorがきちんと伝わっているか確かめる
--dart-define-from-file
がきちんとネイティブに伝わり、アプリ名やBundle IDがFlavorごとに変更されていることを手軽に確かめるためには、 package_info_plus
パッケージを使用します。
PackageInfo
の下記メソッドを使用して確認できます。
-
.appName
- iOS: アプリ名 (
CFBundleDisplayName
) - Android:
android:label="@string/app_name"
- iOS: アプリ名 (
-
.packageName
- iOS: Bundle ID (
CFBundleIdentifier
) - Android:
applicationId
- iOS: Bundle ID (
さいごに
最後まで読んでいただきありがとうございました😊
宣伝
Altive株式会社では、Flutterアプリの開発・運営を承っております。
お気軽にお問い合わせください🫡
Riverpod の実践入門本を公開中です📘
参考記事
Discussion
暗号化ではなく、エンコードです。
秘匿する目的ではなく、渡されたパラメーターの値を後から正確に展開するための処理のはずです。
暗号化と表現すると、ここにセキュアな値を入れても良いかのような誤解を招きそうですが、そうではないので。
これは恥ずかしい…!monoさん、ご指摘ありがとうございます☺️
修正しました👌
記事わかりやすく、とても参考になりました!
ありがとうございます🙇
自分が利用していて気づいたことなのですが
このDart-defineを使った上でfirebaseを新規導入する際は
Copy Bundle ResourcesにSelect GoogleService-Info.plistで
コピーされたGoogleService-Info.plistを追加しないと
GoogleService-Info.plistが読み込まれずfirebaseを使うことができないみたいです!
@akaboshinit さん、追加情報ありがとうございます✨
遅くなってしまいましたが、記事に追記させていただきました🙌
Flavor対応参考にさせていただきました。
--dart-define
が出る前の名残でflutter_flavorizr | Flutter Package辺りを使って凌いでましたが、記事の通り進めたらさくっとできました。ありがとうございます。1点アプリアイコンの切り替えについてですが、出力までの手順に留まっており反映の記述が漏れている様子でしたので、間違いなさそうであれば追記お願いします🙏
(私の環境ではこちらの設定なしではアイコン反映できずでした)
ツルオカさん、ご報告ありがとうございます🙏😊
後ほど追記させていただきます!
ここに関してのコメントですが、Downloadフォルダ等からではなく、Runnerディレクトリにコピーされて出来上がったものをドラッグアンドドロップして参照するようにするのが良いと思います!(ダウンロードフォルダからとかだと参照のディレクトリが違くて、「
Cannnot find ~/GoogleService-Info.plist
」みたいなエラーが出そうです!)kboyさん、コメントありがとうございます😊
Xcodeでドラッグ&ドロップする際に、
Copy items if needed
にチェックすれば、Downloadフォルダにあるファイルへの参照ではなく、新規にファイルを作成して配置してくれるので参照エラーは出ない認識でした…!試してみて問題あるようだったら修正しますね💪
なるほどです!そしたらコピーされるので大丈夫かもです!!
Flavor対応参考にさせて頂きました〜!
記事通り進めるだけで手軽にできて驚きました、ありがとうございます!!
もし良ければスクラップに残しておいたので使ってください!🎯
Daigoさん、サポートありがとうございます!!
またAndroid Studioの設定例もありがとうございます🙌
後ほど記事更新してリンクさせていただきます😊
久々にアイコン差し替えの対応をすることがあって、忘れてしまっていた部分が多かったので参考にさせていただきました 🙏
Androidのアイコン差し替えですが、設定でビルド時に
src/main/res
とsrc/${flavor}/res
をマージすることができるので、それを使ったほうが綺麗かなと思います。ありがとうございます!!Androidの知見少ないのでありがたいです🙌
後ほど使わせていただくと思います!
参考になる記事をありがとうございます!
launch.json
の参考例ですが、余計な{
が4行目に含まれているようなので一応記載しておきます!kyam_28さん
{
が二重にありますね!ありがとうございます、修正します🙌記事とても参考になりました。ありがとうございます。
macOSでしか動作確認をしておりませんが、
Select GoogleService-Info.plist
はCompile Sources
よりも上にしないと環境が適切に切り替わらなかったように見受けられました。もしどなたかのご参考になりましたら。大変参考になりました。ありがとうございます🙌
CFBundleName とは、と自身も改めて確認したところ
とあったので CFBundleDisplayName があれば不要そうでした。自分は CFBundleDisplayName をセットしてCFBundleName を削除してみたところ、正常にビルドされました🙋♂️
Kirkさん、ありがとうございます🙌
CFBundleName
を削除しても問題なくビルド可能なんですね👏✨もしかしたら環境によるかもしれませんが、
CFBundleName
は出力したipa
ファイルの名前になるようです👀(
CFBundleName
がsample
の場合はsample.ipa
になる)しかし、このとき
CFBundleName
に日本語が含まれていた場合省略されるようです。(
CFBundleName
がサンプルapp
の場合、「サンプル」部分が省略されてapp.ipa
になる)なので、
CFBundleDisplayName
が日本語のアプリなどは分けて定義するメリットがあるかもしれませんね✍️わざわざコメントありがとうございます!
実はコメントしたあとに「Archive はどうなるんだ…」と気になってました。笑
さらに逆に勉強になりました。ありがとうございます🙏
いつもこの記事のお世話になっております🙇
iosのGoogleService-info.jsonの位置がRnner/Runner配下でないと動かない仕様?になっている気がしましたがどうでしょうか?
また、大変分かりやすいので、Firebase CLI版(androidは変わらず、iosのfile名が変わっただけかもですが...)も執筆していただけることを心待ちにしております!
龍之介さん!
すみません、こちらのコマンドを打つ前にbuild.gradlededで、minSdkVersionに数値を入力しないとエラーが出てしまうようです!
最近は、Flutter SDK本体の設定をいじれば、数値を設定できていたのですが、flutter_launcher_iconsは違うみたいです!
驚きました!
flutter pub run flutter_launcher_icons:main
エラーログ
非常に参考になり助かりました🙏
要ないかもしれませんが、dart-defineを外してビルドした際にデフォルトでdevのアイコンをセットできるようにもしてみたので共有です。
とても遅くなってしまいましたが、
build.gradle
の記法など勉強になります!共有ありがとうございます🙌
--dart-define-from-file が利用可能になったので、かなり設定が楽になりましたね
ありがとうございます!
--dart-define-from-file
使って、記事書き換えてみました👍こちらの記事のおかげでアプリ名の出しわけができました!
とても役に立つ記事、ありがとうございます。
前回記事からお世話になっています。ありがとうございます。
Select GoogleService-Info.plistのスクショで記入されているコピーコマンド、
cp -f ${SRCROOT}/${FLAVOR}/GoogleService-Info.plist ${SRCROOT}/GoogleService-Info.plist
は
cp -f ${SRCROOT}/${flavor}/GoogleService-Info.plist ${SRCROOT}/GoogleService-Info.plist
ですね(実際作業してたら間違えないと思いますが)。
また、Web (Firebase Hosting 使用)ですが、以下でちゃんと環境分けできてます。
遅くなりましたが、補足コメントありがとうございます🙌
flavor
の大文字・小文字のミスですね。あとで修正いたします🙏役に立ちました。
extentionを使っていると、ビルド時に次のエラーで失敗します。
この記事の方法とコメントで対応できました。
遅くなりましたが、extensionを使用した場合の補足とコメントありがとうございます🙌
This is really helpful, Thank you
この記事の内容ですが、Flutter 3.17で動作しなくなる可能性が高そうです 😱
コメントありがとうございます!残念ですがそうなりそうですね🥶
古い方の記事残しておいたのでこちらの内容をまた追記することになりそうです…
前回の記事からお世話になっています。ありがとうございます。
dart_defines/dev.env の googleReversedClientId の行の最後に「,」が入っていますが、「,」があると「"」と「,」が残ったまま環境変数が設定されてしまうようです。
googleReversedClientId の出力例
dart_defines のファイルは「,」を削除した以下の形が正しいかと思います。
google認証をしようとした際に、アプリがクラッシュされる方がいらっしゃったらこれが原因かもしれません。
ご指摘ありがとうございます!JSONファイルの時の末尾カンマが残ってしまっていたみたいです…!
修正します🙌
この構成でプロジェクトを作った場合って、apiKeyなどのセキュアなものってどこで持たせるのがいいのでしょうか。そこだけ綺麗にできずに困ってます。
秘密鍵などのセキュアなものはアプリに入れてしまうと、成果物から解読されるリスクが高い認識です。
なので、原則サーバーサイドで管理するのが良いかと思っています。
それがどうしても難しい場合は envied等を使って難読化するのが妥協案になりそうです。
返信ありがとうございます。
他の方の記事とかで.envにapiKeyを入れてる方がちらほらいたので気になりました。
privateのリポジトリにあげるとしてもアプリ自体を解析されてしまう可能性があるんですね。その辺の知識がなかったので勉強になりました。
build.gradleを編集してdart-defineを受け取るの部分でちょっとハマりそうな挙動を発見したので報告です。
こんな感じにvalueが空の変数を定義したときに
pair.first()とpair.last()が両方hogeとなり、keyもvalueもhogeのmapになるみたいです。
対策としてはlengthが2でない場合に空のmapにするなどが考えられそうです。
以下は実際にこのケースに遭遇した際に対応したIssueです。
報告ありがとうございます🙌
なるほど!空文字の値を設定してしまうと、
last
もpair
もKeyの方を参照してしまうんですね…!勉強になりました✍️
後ほど対策取り入れさせていただくと思います🙏