Skip to content

Starter kit for Flutter, some feature are auth, notifications, biometric, profile, theme, localizations and more

Notifications You must be signed in to change notification settings

Flowlabsio/flutter_starter_kit

Repository files navigation

image

Developed by Flow Labs 🚀

Flutter Kit

This starter kit was created to address the challenges of initializing a project. At Flow Labs, we identified recurring patterns when starting a project: state management, authentication, forms, alerts, snackbars, styles, authentication, users, rules and more. The idea behind this repository is to consolidate all the knowledge we’ve gained from building apps into a single resource.

This kit is not a "framework"; rather, it's a guide for initializing a project with useful tools, popular libraries, folder structures, widgets, and more. The key idea is flexibility: developers have the freedom to choose their preferred structure. The goal of this repository is to be a helpful starting point without imposing rigid constraints on developers.

Screenshots

WhatsApp.Video.2025-01-14.at.02.12.07.mp4
WhatsApp.Video.2025-01-16.at.03.39.25.mp4

Platforms

  • Android
  • IOS

Features

  • Sign In
    • Google
    • Apple
    • Facebook
  • Sign In/Up Email-Password
    • Email/Password
    • Validate Email
    • Forgot Password
    • Reset Password
  • Profile
  • Locked Screen (Biometric)
  • Preferences
    • Language
    • Theme
      • Light
      • Dark
  • Delete User
  • Local Notifications
    • Push Notifications
    • Schedule Push Notifications
    • Listeners
  • Notifications Screen
  • Public Onboarding
  • Emulators
  • Export data

Index

  • Download Kit
  • Firebase
    • Install firebase CLI
    • Create firebase projects
    • Configuration services
      • Authentication
        • Google
        • Apple
        • Facebook
        • Email and password
      • Firebase Database
      • Storage
      • Functions
    • Deploy
      • Rules
  • Flutter App
    • Configuration initial project
      • Install VGV project
      • Add dependencies
      • Copy the app_initial
      • Set Firebase environments in the project
    • Create the app
    • Install the kit
  • Set platforms
    • IOS
      • Set BundleId
      • Set Min Version iOS
      • Add Permissions
      • Sign in with Apple
      • Sign in with Google
      • Sign in with Facebook
        • Set Bundle ID
        • Set Bundle ID (Alternative)
        • Set env Info.plist
      • Edit AppDelegate
      • Set Push Notifications from Firebase
        • Xcode
        • Apple Developer and Firebase
      • Biometric
    • Android
      • Set Namespace
      • Update min-sdk-version
      • Sign in with Google
      • Sign in with Facebook
        • Set Facebook keys
        • Set Hashes and Package Name
        • Set Hashes and Package Name (Alternative)
      • Biometric config
      • Config Schedule Notification
      • Biometric
  • Emulators
  • Export data from Firebase
    • Firebase Auth
    • Firestore
  • Notifications
    • Local
    • Remote

Download Kit

This is the first step to do something with the kit

git clone https://github.com/Flowlabsio/flutter_starter_kit.git <project-name>

cd <project-name>

# Open project with vscode
code .

Firebase

Install firebase CLI

# Download CLI
curl -sL https://firebase.tools | bash

# Or from npm
npm install -g firebase-tools

# Login in firebase
firebase login

Create firebase projects

We will go to create the firebase projects for each environment

  1. Open firebase/Makefile and rename the var PROJECT_NAME

Clarification: If you will have more than three envirnments, add you other envirnments in the var ENVIRONMENTS on firebase/Makefile

  1. Create the projects for each envirnments
cd firebase

make create_firebase_project

This command could be failed because the name is used on another project (and the names of the projects could be unique), if that happen try to run the next command for each failed project

firebase projects:create <project-name>-<env>

Or go to the console and drop the projects created and start again this process. Or create manually

Configuration services

This configuration is the basic setup to use the app_initial this app use four services in Firabase, Authentication and Firestore Database, Storage and Functions

image

You must to cofig every services in each environment. Or if you want to only start with development (or another) you can only set that and then the another environments

Authentication

The Sign-in methods should be three

  1. Email and password (iOS and Android)
  2. Google (iOS and Android)
  3. Apple (iOS)
image
Google
  1. Select "Google"
image
  1. Set enable and set the facing name (you can change this later)
image

You will see this title when you try to sign-in with Google in the app.

image
  1. Press "Save"
image
Apple
  1. Select "Apple"
image
  1. Press "Save"
image
Facebook

Clarification: The Auth Emulator does not support facebook.com sign-in

  1. Create an app in Facebook console (https://developers.facebook.com/)

Clarification: You could create an app for environment

image
  1. Select the Auth service
image
  1. Select "I don’t want to connect a business portfolio yet."
image
  1. Go to App Settings -> Basic
image
  1. Copy the "App ID" and the "App secret"
image
  1. Go to Firebase Console and add Facebook provider in the Authentication service
image
  1. Paste the "App ID" and the "App secret", set enabled and press "Save"
image
  1. Press "Edit" facebook provider
image
  1. Copy the OAuth redirect link
image
  1. Go back to the Facebook dashboard, press "Use cases"
image
  1. Press "Customize"
image
  1. Select "Settings"
image
  1. Look the input "Valid OAuth Redirect URIs" and paste the OAuth redirect link from Firebase
image
  1. Select "Permissions"
image
  1. Look "email" and press "Add"
image
  1. Go to App Settings -> Basic (again)
image
  1. Got to App roles -> Roles
image
  1. Press "Add People"
image
  1. Add the user that are allow to use this service (facebook username). This user should have an facebook developer account
image
Email and password
  1. Select "Email/Password"
image
  1. Press "Save"
image

Firebase Database

  1. Enter in "Firebase Database" and press in "Create Database"
image
  1. Choose a location
image
  1. Press "Create"
image

Storage

Both Storage and Functions will need to set a "Billing Account". This point is important because if you dont do that you won't be able to use this services instead with the emulators

  1. Go to the "Storage" section and press "Upgrade project"
image
  1. If you have an account, choose one of them, otherwise, create one
image
  1. Set a budget
image
  1. After that you will see the button "Get started", press it
image
  1. Select your location
image
  1. Press "Create"
image

Functions

  1. Press "Get started"
image
  1. Press "Continue"
image
  1. Press "Finish"
image

Deploy

Rules

Go to /firebase and select the project firebase use <project-name>-<env>

Deploy the rules to Firebase

firebase deploy --only firestore:rules
firebase deploy --only storage

Flutter App

This starter kit use the template of Very Good Ventures to generate the app. The team believe it's a great standard to lunch an app. Therefore we will follow the next steps to install the CLI and generate the app.

Install VGV project

  1. Install the VGV CLI
dart pub global activate very_good_cli
  1. Run one by one the commands to create the project and leave every file and file in the root folder
# Go to the root of the project

# Create the project
very_good create flutter_app <project-name>

# Copy project files
rsync -avh --ignore-existing <project-name>/ .

# Delete the other project
rm -rf <project-name>

Add dependencies

flutter pub add app_ui --path=./kit/app_ui
flutter pub add app_core --path=./kit/app_core
flutter pub add app_helpers --path=./kit/app_helpers

flutter pub add freezed_annotation
flutter pub add dev:build_runner
flutter pub add dev:freezed
flutter pub add json_annotation
flutter pub add dev:json_serializable
flutter pub add dev:icons_launcher

flutter pub add go_router \
  equatable \
  flutter_native_splash \
  reactive_forms \
  google_sign_in \
  sign_in_with_apple \
  flutter_facebook_auth \
  firebase_core \
  firebase_auth \
  cloud_firestore \
  firebase_storage \
  image_cropper \
  image_picker \
  permission_handler \
  shared_preferences \
  internet_connection_checker_plus \
  device_info_plus \
  firebase_messaging \
  flutter_local_notifications \
  timezone \
  crypto \
  smooth_page_indicator \
  local_auth

And update the version

flutter pub upgrade --major-versions

Copy the app_initial

  1. Delete the folders
rm -rf lib/app lib/counter test/counter
  1. Update app_test.dart
echo "import 'package:flutter_test/flutter_test.dart';

void main() {
  group('App', () {
    testWidgets('', (tester) async {
      expect(true, true);
    });
  });
}" > test/app/view/app_test.dart
  1. Replace localizations
rm -rf lib/l10n && mv kit/app_initial/lib/l10n lib/l10n
  1. Move the kit/app_initial/lib/src to lib/
cp -r kit/app_initial/lib/src lib/
  1. Go to kit/app_initial/lib/bootstrap.dart.template copy the content and paste in lib/bootstrap.dart
cp kit/app_initial/lib/bootstrap.dart.template lib/bootstrap.dart
  1. Run this command to fix the path's dependencies
./replace_text.sh ./lib "app_initial" "<project-name>"

flutter pub get
  1. Go to every main_<env> and fix the App dependencie
import 'package:<project-name>/src/app/app.dart';
  1. Delete the folder kit/app_initial
rm -rf kit/app_initial

Set Firabase environments in the project

Before to start with this step remember to finish all the steps about create projects in the "Firebase" section

  1. Instal flutterfire_cli to config the firebase console with the app
dart pub global activate flutterfire_cli
  1. Then config run this command
./configure_firebase.sh \
    --project="<project-name>-<env>" \
    --ios-bundle-id="com.<org>.<project-name>.<env>" \
    --android-package-name="com.<org>.<project-name>.<env>" \
    --env="<env>"
  1. Set the platforms
image

If you go to

image

At the seccion "Your apps", you will see your apps

image

Will apear four new files in environments/<env>/.

* firebase_options.dart
* GoogleService-Info.plist
* google-services.json
* firebase.json

After run the project with vscode, this files with be paste in their correct position

* lib/firebase_options.dart
* ios/Runner/GoogleService-Info.plist
* android/app/google-services.json
* firebase.json

Repeat this process for each environment (if you configurated the other environment).

  1. From the root of the project run make <env> to paste the firebase config files in their positions (this proccess in automatic with vscode)

  2. Go to lib/bootstrap.dart and uncomment this lines

/// UNCOMMENT THIS LIKE AFTER ADDING FIREBASE CONFIGURATION
// await Firebase.initializeApp(
//   options: DefaultFirebaseOptions.currentPlatform,
// );
  1. Delete old .git with rm -rf .git

Set plaforms

IOS

Set BundleId

  1. Open xcode
open ios/Runner.xcworkspace
  1. Press on "Runner"
image
  1. Go to "Signing & Capabilities"
image
  1. Set the bundle id and team for each team (remember that the bundle id must match with the bundle id create in firebase console)
image

Set Min Version iOS

In the Podfile set the min version in 13 (required by firebase_auth). Go to ios/Podfile, paste

platform :ios, '13.0'

Add Permissions

In the Podfile paste in the final

post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)

    target.build_configurations.each do |config|
      # You can remove unused permissions here
      # for more information: https://github.com/BaseflowIT/flutter-permission-handler/blob/master/permission_handler/ios/Classes/PermissionHandlerEnums.h
      # e.g. when you don't need camera permission, just add 'PERMISSION_CAMERA=0'
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',

        ## dart: PermissionGroup.camera
        'PERMISSION_CAMERA=1',

        ## dart: PermissionGroup.microphone
        'PERMISSION_MICROPHONE=1',

        ## dart: PermissionGroup.photos
        'PERMISSION_PHOTOS=1',

        ## dart: PermissionGroup.notification
        'PERMISSION_NOTIFICATIONS=1',
      ]
    end
  end
end

Sign in with Apple

  1. Press on "Runner"
image
  1. Go to "Signing & Capabilities"
image
  1. Press
image
  1. Add "Sign in with Apple"
image

Sign in with Google

  1. Go to environments/<env>/GoogleService-Info.plist and copy the value of the key REVERSED_CLIENT_ID and past it in the environments/<env>/Info.plist in the CFBundleURLSchemes

If you can't find the REVERSED_CLIENT_ID it's because the Sign in with Google configuration in firabase is missing.

<dict>
    <!-- Put me in the [my_project]/ios/Runner/Info.plist file -->
    <!-- Google Sign-in Section -->
    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeRole</key>
            <string>Editor</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <!-- TODO Replace this value: -->
                <!-- Copied from GoogleService-Info.plist key REVERSED_CLIENT_ID -->
                <string>[REVERSED_CLIENT_ID]</string>
            </array>
        </dict>
    </array>
    ...
</dict>
  1. Go to environments/<env>/GoogleService-Info.plist and copy the value of the key CLIENT_ID and past it in the environments/<env>/env.json in the GOOGLE_CLIENT_ID
{
  ...
  "GOOGLE_CLIENT_ID": "<CLIENT_ID>",
  ...
}

Sign in with Facebook

Set Bundle ID
  1. Go to App Settings -> Basic
image
  1. Scroll to the bottom of the page and press "Add platform"
image
  1. Select iOS
image
  1. Fill the Bundle ID and press "Save changes"
image
Set Bundle ID (alternative)
  1. Go to https://developers.facebook.com/docs/facebook-login/ios

  2. Select the app

image
  1. Add your Bundle ID and press "Save"
image
Set env Info.plist
  1. Go to App Settings -> Basic
image
  1. Copy the App Id and go to environments/<env>/Info.plist

Replace the FACEBOOK_APP_ID by the id (there are two places)

  1. Go to App Settings -> Advanced
image
  1. Copy the Client token and go to environments/<env>/Info.plist

Replace the FACEBOOK_CLIENT_TOKEN by the token

  1. Replace the FACEBOOK_DISPLAY_NAME by the name what you want to show to the user

Edit AppDelegate

  1. Edit application method
override func application(
  _ application: UIApplication,
  didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
  FlutterLocalNotificationsPlugin.setPluginRegistrantCallback { (registry) in
    GeneratedPluginRegistrant.register(with: registry)
  }
  GeneratedPluginRegistrant.register(with: self)
  if #available(iOS 10.0, *) {
    UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
  }
  return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
  1. Add import
import flutter_local_notifications

Set Push Notifications from Firebase

Xcode
  1. Open xcode open ios/Runner.xcworkspace

  2. Press Runner -> Signing & Capability

image
  1. Press "+ Capability"
image
  1. Add "Push Notifications"
image
  1. Press "+ Capability" again
image
  1. Add "Background Modes"
image
  1. Select "Background fetch" and "Remote notifications"
image
Apple Developer and Firebase

This key will use for testing and development environment. You can even use this key in another apps, but is not recommended because if you revoke the key, every app that use the key will lose the services

  1. Go to Apple Developer (https://developer.apple.com/account)

  2. Go to "Keys"

image
  1. Add a new key and select the service "Apple Push Notifications service (APNs)"
image
  1. Download the key
image
  1. Go to Firebase console -> Project settings
image
  1. Go to "Cloud Messaging"
image
  1. Scroll down and set your key
image

Biometric

Uncomment these lines in environments/<env>/Info.plist

<!-- Biometric -->
<!-- <key>NSFaceIDUsageDescription</key>
<string>The app requires access to Face ID</string> -->
<!-- Biometric -->

Android

Set Namespace

  1. Intall the next package
flutter pub add --dev change_app_package_name
  1. Run the command
dart run change_app_package_name:main com.<org>.<project-name> --android

Update build.gradle

Go to android/app/build.gradle

  1. Set minSdkVersion
minSdkVersion 23
  1. Add multiDexEnabled
android {
  defaultConfig {
    multiDexEnabled true
    ...
  }
  ...
}
  1. Set compileSdk
compileSdk 34

Sign in with Google

  1. Excecute
# Debug
keytool -list -v -alias androiddebugkey -keystore ~/.android/debug.keystore -storepass android -keypass android
  1. Copy the SHA1 and go to the firebase console
image
  1. Go to "Project settings"
image

And select the android app

image
  1. Press in "Add fingerprint"
image
  1. Paste the SHA1 and press "Save"

  2. Update the environment files with the command ./configure_firebase.sh (check the documentation about generate if you forgot the process)

Sign in with Facebook

  1. Go to environments/<env>/AndroidManifest.xml and uncomment the lines between <!-- Facebook -->
Set Facebook keys
  1. Go to Facebook console and press App Settings -> Basic
image
  1. Copy the "App id"
image
  1. Go to environments/<env>/strings.xml and paste in the facebook_app_id section

  2. Go to Facebook console, and press App Settings -> Advanced

image
  1. Copy the "Client token"
image
  1. Go to environments/<env>/strings.xml and paste in the facebook_client_token section
Set Hashes and Package Name
  1. Go to App Settings -> Basic
image
  1. Scroll to the bottom of the page and press "Add platform"
image
  1. Select Android
image
  1. Select the stores
image
  1. Fill inputs
image

To generate the hashes use (use password: "android"):

For development

keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64

For production

# Generate a keystore for porduction
keytool -genkeypair -v -keystore release-key.keystore -keyalg RSA -keysize 2048 -validity 10000 -alias  release-key

keytool -exportcert -alias release-key -keystore release-key | openssl sha1 -binary | openssl base64

After set every field press "Save"

image
Set Hashes and Package Name (Alternative)
  1. Go to this link https://developers.facebook.com/docs/facebook-login/android/

  2. Select the app

image
  1. Associate Your Package Name and Default Class
image
  1. Press "Save"
image
  1. Add the Key Hashes
image

To generate the hashes use:

For development

keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64

For production

keytool -exportcert -alias YOUR_RELEASE_KEY_ALIAS -keystore YOUR_RELEASE_KEY_PATH | openssl sha1 -binary | openssl base64

If you got this error

image

Copy that hash in the hashes list in Facebook Console

Error Emulator

If you got this error

An internal error has occurred. Cleartext HTTP traffic to 10.0.2.2 not permitted

Go to AndroidManifest.xml and this flags

<application
    ...
    android:usesCleartextTraffic="true"
    android:enableOnBackInvokedCallback="true"
    ...
    >

Biometric config

  1. Go to android/app/src/main/kotlin/com/<org>/<project-name>/MainActivity.kt

  2. Edit the MainActivity.kt

import io.flutter.embedding.android.FlutterFragmentActivity

class MainActivity: FlutterFragmentActivity() {
}

Config Schedule Notification

  1. Go to environments/<env>/AndroidManifest.xml and uncomment the lines between. Check the manifest and application context because there are two blocks
<!-- Schedule Notifications -->
...
<!-- Schedule Notifications -->

Biometric

Uncomment these lines in environments/<env>/AndroidManifest.xml

<!-- Biometric -->
<!-- <uses-permission android:name="android.permission.USE_BIOMETRIC"/> -->
<!-- Biometric -->

Emulators

To use the emulators, it's necessary to choose a real firebase project, use one of created before (recommended dev environment).

Clarification: If you want to use any service in the emulator, that service must be activated in the firebase project, for example "Google Sign In", the provider of google should be activated to use it in the emulator

Run emulators

To start the emulator run

cd firebase

firebase use <project-name>-<env>

firebase emulators:start --import export/ --export-on-exit export/

Functions

Install the function dependencies (if you want to use it)

cd firebase/functions

python3 -m venv venv

source venv/bin/activate

pip install -r requirements.txt

Config App

In the app, uncomment this lines in the bootstrap.dart

/// USE EMULATORS
FirebaseFirestore.instance.useFirestoreEmulator('localhost', 8080);
await FirebaseAuth.instance.useAuthEmulator('localhost', 9099);
await FirebaseStorage.instance.useStorageEmulator('localhost', 9199);

Export data from Firebase

Clarification: There isn't a "native" way to export the data from firebase and insert in the emulator,

Firebase Auth

# Select the project
firebase use <project-name>-<env>

# Export data
firebase auth:export export/firebase_users.json --format=JSON --project <project-name>-<env> 

Firestore

  1. Install firestore-export-import
npm install -g firestore-export-import
  1. You have to generate new private key from "Project Settings" from Firebase Console.
image
  1. Go to "Service Account" tab
image
  1. And press "Generate new private key"
image
  1. Move the key serviceAccountKey.json to the folder firebase/

  2. Run

cd firebase

firestore-export -a ./<service-account-key>.json -b ./<data-namefile>.json

Notifications

Local

There is a class call LocalNotificationHelper and that be able to send notifications. There is two types of notifications instant or scheduled. To use the instant notification call LocalNotificationHelper.instance.showNotification() and for the scheduled .scheduleNotification(). To remove a scheduled notification use .cancelNotification()

Also this class have three listeners

  • onBackgroundMessage: This method is executed when the app receives a notification in killed or background
  • onMessage: This method is executed when the app receives a notification in foreground
  • onMessageOpenedApp: This method is executed when the app receives a notification and the user tap on it, a that open the app

Remote

To use the service there are many options (Firebase Cloud Messaging API, Cloud Functions, use your own service or third-party service with the server). This decision depends on the developer team and available resources. To test the remote push notification there is a function in Cloud Functions that send notifications to each device of a user. This service work in the emulator but remember active the service in Firebase Console. Every request to this service generate a notification document to the user in Firestore

From emulator

curl -X POST http://127.0.0.1:5001/<project-name>-<env>/<region>/send_notification \
     -H "Content-Type: application/json" \
     -d '{
         "wheres": [
             {"field": "id", "operator": "==", "value": "<user-id>"}
         ],
         "data": {"key": "value"},
         "title": "Title",
         "body": "Body"
     }'

From Firebase

curl -X POST https://<region>-<project-name>-<env>.cloudfunctions.net/send_notification \
     -H "Content-Type: application/json" \
     -d '{
         "wheres": [
             {"field": "id", "operator": "==", "value": "<user-id>"}
         ],
         "data": {"key": "value"},
         "title": "Title",
         "body": "Body"
     }'

Another option to test the remote notifications is with the offered service by Firebase. Find the FCM token in firestore users/{id}/devices/{id} the attribute fcmToken

image

Testing

# Generate `coverage/lcov.info` file
flutter test --coverage
# Generate HTML report
# Note: on macOS you need to have lcov installed on your system (`brew install lcov`) to use this:
genhtml coverage/lcov.info -o coverage/html
# Open the report
open coverage/html/index.html

Edit app name iOS (by env)

  1. Open Xcode

  2. Go to Runner -> Build Settings

image
  1. Filter by FLAVOR_APP_NAME. You will see the current names
image

About

Starter kit for Flutter, some feature are auth, notifications, biometric, profile, theme, localizations and more

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages