A base Flutter application with mvvm architecture
https://fvm.app/docs/getting_started/installation
Step 1 : Install Firebase CLI with npm : "npm install -g firebase-tools"
https://firebase.google.com/docs/cli#install-cli-mac-linux
Step 2 : Login to firebase account : "firebase login"
Step 3 : Install FlutterFire CLI with this command : "dart pub global activate flutterfire_cli"
Step 4 : Configure multi flavor with:
Run command "flutterfire configure -i packageName -a packageName -o lib/firebase/firebaseoptions{flavor}.dart" for each flavor.
Dev: "flutterfire configure -i com.vmo.c3FlutterTemp.dev -a com.vmo.c3FlutterTemp.dev -o lib/firebase/firebase_options_dev.dart"
Staging: "flutterfire configure -i com.vmo.c3FlutterTemp.staging -a com.vmo.c3FlutterTemp.staging -o lib/firebase/firebase_options_staging.dart"
Production: "flutterfire configure -i com.vmo.c3FlutterTemp -a com.vmo.c3FlutterTemp -o lib/firebase/firebase_options.dart"
Other configure:
Documentation at : https://firebase.google.com/docs/flutter/setup?platform=ios
Step 2 : Create new Configuration with build flavor value is :
project
|--.fvm # fvm config using for project
| |--fvm_config.json # config file
|--android # android project dir
|--assets # application all assets
| |--images # application image assets
| |--fonts # application font assets
|--ios # ios dir
|--lib # main project dart lib entry point
| |--config # configuration for project
| | |--app_config.dart # config enum flavor and baseURL (development, staging, production)
| | |--colors.dart # config for color
| | |--navigation_util.dart # config navigation key and nested navigation key
| | |--styles.dart # config for text styles
| | |--theme.dart # config for theme for project
| |--core # core project include string extension, int extension, double extension,...
| | |--string.dart # string extension function
| | |--double.dart # double extension function
| |--firebase # firebase config that auto generated by Firebase CLI
| |--repositories # repositories layer for mvvm architecture
| | |--login # login feature folder
| | | |--models # login model request and response folder
| | | |--login.dart # export file for import in other place
| | | |--login_api.dart # api abstract class on retrofit
| | | |--login_api.g.dart # api generate class on retrofit
| | | |--login_repository.dart # repository class for login feature
| | |--utils # utils for data layer
| | | |--exceptions # custom exception for repository layer
| | | |--share_pref_manager.dart # Share preferences manager class (include share preferences key enum)
| |--ui # ui layer for mvvm architecture
| | |--common # common widget or common screen
| | |--login # login ui layer
| | | |--bloc # login bloc for whole login screen
| | | |--ui # ui folder for login feature
| | | | |--login_screen.dart # login ui frame
| | | | |--widgets # widgets folder for nested widget in login feature
| | | |--login_route.dart # login route class define BlocProvider for Bloc class of login feature
| |--utils # utility folder for project
| | |--di # dependencies injection registration for project
| | |--multi-languages # localization for project, using easy_localization and google sheet generator csv
| | |--route # route config for project, include generateRoute and route define all screen of project
| | |--session_utils.dart # session utility for project like getAccessToken or something using common most
| |--main.dart # main config Material App and runApp
|--test # unit test
|--web
|--.gitignore # ignore file of git
|--fastlane # config ci/cd using fastlane
|--README.md # ReadMe for this project
|--analysis_options.yaml # lint rule configuration, config rule here
|--.gitlab-ci.yml # config ci/cd for gitlab
|--pubspec.yaml # dart package management file, add new dependencies here
|--.setup_app.sh # Script to set up app before run app
|--.setup_env_config.sh # Script to set up environment variable to display on ci/cd
|--.setup_fastlane.sh # Script to set up fastlane config before run ci/cd
|--..build_android.sh # Script to build android on local
getIt.registerSingleton<LoginBloc>(LoginBloc(
loginUseCase: LoginUseCase(getIt<LoginRepositoryImpl>()),
));
and use it on route
BlocProvider<LoginBloc>(
create: (_) => getIt.get<LoginBloc>(),
),
for reusing the BLoC
,
BlocProvider.value(
value: getIt.get<PumpsBloc>(),
)
for usage (in Widgets), always use
context.boc<PumpsBloc>().add(AddPumps());
instead of
getIt.get<PumpsBloc>().add(AppPumps());
For non widget usage, manually inject the object on initialization.
We are using Easy Localization to handle multi-languages. Using Google Sheet Generator on cloud will take less effort for change and update key and value. Only need update in google sheet file. (Using only one way, csv or json)
Google sheet sample on this project : "https://docs.google.com/spreadsheets/d/1SpiJWFRfJaIRnzpEc0mJ2WaaI9JYlz8jKBPduAPzdXE/edit#gid=1013756643"
Step to set-up google sheet :
Step to setup json file in project :
Step to use multi-languages import in code:
Remember import file "multi_languages_utils.dart" instead of "locale_keys.dart" because first file already import library easy_localization extension,you no need to use 2 import
Using : LocaleKeys.keyDefine.tr() (tr() is using to change languages with current languages setup, remember have it)
Link library : https://pub.dev/packages/easy_localization Link plugin generate csv from google sheet : https://github.com/Hoang-Nguyenn/easy_localization_generator
This project is implementing json_serializable. It use build_runner to generate files. If you make a change to these files, you need to re-run the generator using build_runner:
flutter pub run build_runner build
generator using build_runner and remove conflict file :
flutter pub run build_runner build --delete-conflicting-outputs
dart pub global activate flutter_gen
assets/<asset types>
flutter pub run build_runner build
in consolelib/gen/assets
assets/<asset types>
flutter pub run build_runner build
in consolelib/gen/assets
will be updated with currently available assets.