12 things I have learnt while building a Flutter app for development and production
Tags: flutter
Published: 2023-01-15 15:40:30

- 1. I went a bit wild changing things in `AndroidManifest.xml`, among which the `package=` property. Well don't, or at least make sure you also change it in the `MainActivity.kt` file. Otherwise it will crash upon loading, like it happened to me. Kudos to [this](https://stackoverflow.com/a/69938943/3630417) answer in SO for putting me on the right direction.

- 2. If you make API calls in your app, you need to specify permissions for internet, read more about it [here](https://docs.flutter.dev/deployment/android#reviewing-the-app-manifest). [This](https://docs.flutter.dev/cookbook/networking/fetch-data) Flutter cookbook can also be helpful.

- 3. Multidex support. You can read about it [here](https://docs.flutter.dev/deployment/android#enabling-multidex-support). The docs say that `The simplest way is to opt into multidex support when prompted.`. I was wondering: prompted when? From what I have seen when trying to run the app on an android device for development, you get indeed prompted, so just say `y`:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k2gp1zbwhodfysts13dw.png)

- 4. When running your local env in an Android phone, you have access to the Flutter dev tools. You should get the link in the terminal after running `flutter run`:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rjk3ms44sbh0ryaq9ido.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v6808tc5jdugeu73rn1x.png)

-5. `flutter run --verbose` will provide logs of what went wrong. It is helpful.

-6. `flutter logs` will show logs from the devices you are connected to.

-7. You can pass env variables at build time with `--dart-define` (see [here](https://dartcode.org/docs/using-dart-define-in-flutter/)), like so: 

`flutter run --dart-define VARIABLE_ONE=test --dart-define VARIABLE_TWO=42`

or 

`flutter build appbundle --dart-define VARIABLE_ONE=test --dart-define VARIABLE_TWO=42`

([Source](https://stackoverflow.com/a/69349448/3630417))

They can be "fished" in the code [like so](https://api.flutter.dev/flutter/dart-core/String/String.fromEnvironment.html), with a fall back value too. Also explained a bit [here](https://docs.flutter.dev/deployment/cd#cloud-build-and-deploy-setup).

BUT, BIG WARNING: do NOT miss `const` before `String.fromEnvironment()`, otherwise it will silently fail, see https://github.com/flutter/flutter/issues/55870.

Other related and useful articles:

- https://codewithandrea.com/articles/flutter-api-keys-dart-define-env-files/
- https://medium.com/flutter-community/how-to-setup-dart-define-for-keys-and-secrets-on-android-and-ios-in-flutter-apps-4f28a10c4b6c (explains how to pass env variables to android manifest file).
- Careful not to override the default manifest values, so do it like explained [here](https://github.com/flutter/flutter/issues/98316#issuecomment-1046243096).
- [Docs ](https://api.flutter.dev/flutter/dart-core/String/String.fromEnvironment.html)about `String.fromEnvironment` (with the `const`..)

-8. When building for production, you may want to [obfuscate ](https://docs.flutter.dev/deployment/obfuscate) your code to make it harder for malicious actors to find stuff in your code they should not be finding:

`flutter build apk --obfuscate --split-debug-info=/<project-name>/<directory>`

One of the questions I had is.. what is good location for these symbol map files? [This](https://stackoverflow.com/questions/61976886/how-to-use-split-debug-info-project-name-directory) SO thread gave answers, seems like somewhere in `build/` directory is a good place, like `build/app/outputs/symbols`.

-9. Even if you increase the version number of the app, you also need to increase the build number. Otherwise, you will get the `Version code 1 has already been used. Try another version code` error in the Play store. More info [here](https://stackoverflow.com/a/68058025/3630417).

-10. You can "inspect" an .apk or .aab (for app bundle) file in Android Studio to know what value was passed into Android Manifest file (if you are passing a value, ofc). You will need to build from Android Studio (via terminal so u can pass the `--dart-define` variables. You then import the file, and you can find the manifets file in the `/manifest` folder:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z4a5p1eie4fm8i94pcae.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m0wb8f7f6sb5xkn37puw.png)

-11. If you need to troubleshoot what env variables were passed during build, add `.zip` to bundle file (`.apk` or `.aab`). This will make it unzippable. You do so in, for instance, a folder called `unzipped_stuff`, and look for the file `libapp.so` in `\build\app\outputs\bundle\unzipped_stuff\base\lib\arm64-v8a`. Open it in a text editor (I am on windows) and search for the value you passed. If it's there, it worked. If you don't find it, something went wrong. Source [here](https://stackoverflow.com/a/73377932/3630417). Related articles:

- https://medium.com/google-developer-experts/exploring-the-android-app-bundle-ca16846fa3d7 - but haven't read it
- https://developer.android.com/studio/debug/apk-analyzer
- https://developer.android.com/guide/app-bundle/test

-12. If you started versioning your builds, like `1.2.0+6` you need to increment at every build, otherwise Google Play will complain. I learnt this in [this](https://stackoverflow.com/a/68058025/3630417) Stackoverflow thread.