Create flutter project with all needed configuration in two minutes (theme, localization, connect to firebase, FCM, local notifications, safe API call, error handling, animation..etc)

Overview

Flutter GetX Template

Flutter Getx template to make starting project fast and easy .

Introduction

We all face the same problem when we want to start a new project we have to take care of some repeatable things such as

  • Theme (light/dark) & store current theme in shared pref πŸŒ’
  • Localization & store the current locale in shared pref πŸ…°οΈ
  • Firebase Messaging πŸ“¨
  • Notifications setup πŸ””
  • Safe api requests & error handling πŸ”
  • Changing between widgets during api call (loading,success,failed..etc) 😴
  • Snackbar,Toasts & in app notifications πŸͺ–
  • Making app more responsive and stop font scaling βš–οΈ This project will take care of all this repeatable things so you can start your project in few steps and you will have all the mentioned points set up and ready to use 😎

Acknowledgment

Project was created using get_cli which is a great tool helping you to (start project,create screens/controllers, handling DI)..etc and we will list other packages that helped to create this skeleton

Clone and start project

Before discovering folders lets first perform some actions to make the project ready to launch

  • first run this command it will generate hive type adapters (for our custom classes that we want to store locally)

    flutter packages pub run build_runner build --delete-conflicting-outputs
    

    if you don't want to use hive comment this line in main.dart

    await MyHive.init(adapters: [UserModelAdapter()]);
  • To make your app responsive and look exactly as your (xd,figma..etc) design you need to set artbord size for flutter_ScreenUtil in main.dart

    ScreenUtilInit(
      designSize: const Size(375, 812), // change this to your xd artboard size
  • FCM & Awesome Notifications are combined at the same class so when ever you connect your app to firebase your app will be ready to receive notifications you don't need to do anything except sending fcm notification to your api via implementing the method (sendFcmTokenToServer) which is inside FcmHelper class 😎

    static _sendFcmTokenToServer(){
        var token = MySharedPref.getFcmToken();
        // TODO SEND FCM TOKEN TO SERVER
    }
  • Change app package name

    flutter pub run change_app_package_name:main com.new.package.name
    
  • Change app name

    flutter pub run rename_app:main all="My App Name"
    
  • Change app launch icon (replace assets/images/app_icon.png with your app icon) then run this command

    flutter pub run flutter_launcher_icons:main
    
  • FCM: firebase has recently added (add flutter app) to your firebase which will make adding our flutter(android/ios) app to firebase take only 2 steps πŸ”₯ but first you need to download Firebase CLI and in the terminal execute:

    dart pub global activate flutterfire_cli
    

    then follow the firebase guid you will get command similar to this one

    flutterfire configure --project=flutter-firebase-YOUR_PROJECT_ID
    

    and that's it! your project is now connected to firebase and fcm is up and ready to get notifications

Quick Start

  • Responsive app: to make your app responsive you need to get advantage of using flutter_ScreenUtil so instead of using normal double values for height,width,radius..etc you need to use it like this

  • 200.w // adapted to screen width
    100.h // /Adapted to screen height
    25.sp // adapter font size
    10.r // adapter radius
    // Example
    Container(
        height: 100.h,
        width: 200.w,
        child: Text("Hello",style: TextStyle(fontSize: 20.sp,))
    )
  • Theme

    • Change theme

      MyTheme.changeTheme();
    • Check current theme

      bool isThemeLight = MyTheme.getThemeIsLight();
  • Localization

    • Change app locale

      LocalizationService.updateLanguage('en');
    • Get current locale

      LocalizationService.getCurrentLocal();
    • Use translation

      Text(Strings.hello.tr)
  • Safe api call

    • logic code (in controller)

          // api call status
        ApiCallStatus apiCallStatus = ApiCallStatus.holding;
      
        // getting data from api simulating
        getData() async {
          // *) indicate loading state
          apiCallStatus = ApiCallStatus.loading;
          update();
          // *) perform api call
          await BaseClient.get(
            Constants.todosApiUrl, // url
            onSuccess: (response){ // api done successfully
              data = List.from(response.data);
              // -) indicate success state
              apiCallStatus = ApiCallStatus.success;
              update(); // update ui
            },
            // if you don't pass this method base client
            // will automatically handle error and show message
            onError: (error){
              // show error message to user
              BaseClient.handleApiError(error);
              // -) indicate error status
              apiCallStatus = ApiCallStatus.error;
              update(); // update ui
            }, // error while performing request
          );
        }
    • UI: MyWidgetsAnimator will animate between widgets depending on current api call status

      GetBuilder<HomeController>(
      builder: (controller){
        LocalizationService.updateLanguage('en');
        LocalizationService.getCurrentLocal();
        return MyWidgetsAnimator(
            apiCallStatus: controller.apiCallStatus,
            loadingWidget: () => const Center(child: CircularProgressIndicator(),),
            errorWidget: ()=> const Center(child: Text('Something went wrong!'),),
            successWidget: () =>
               ListView.separated(
                itemCount: controller.data!.length,
                separatorBuilder: (_,__) => SizedBox(height: 10.h,),
                itemBuilder: (ctx,index) => ListTile(
                    title: Text(controller.data![index]['userId'].toString()),
                    subtitle: Text(controller.data![index]['title']),
                  ),
              ),
      
        );
      },
      )
  • Snackbars (in app notify):

    CustomSnackBar.showCustomSnackBar(title: 'Done successfully!', message: 'item added to wishlist');
    CustomSnackBar.showCustomErrorSnackBar(title: 'Failed!', message: 'failed to load data');
    CustomSnackBar.showCustomToast(message: 'added to card');
    CustomSnackBar.showCustomErrorToast(message: 'added to card');

          

Discovering Project

After setting up all the needed thing now lets talk about folder structure which is mainly based on Getx Pattern and there are some personal opinions, if you open your lib folder you will find those folders

.
└── lib
    β”œβ”€β”€ app
    β”‚   β”œβ”€β”€ components
    β”‚   β”œβ”€β”€ data
    β”‚   β”‚   β”œβ”€β”€ local
    β”‚   β”‚   └── models
    β”‚   β”œβ”€β”€ modules
    β”‚   β”‚   └── home
    β”‚   β”œβ”€β”€ routes
    β”‚   └── services
    β”œβ”€β”€ config
    β”‚   β”œβ”€β”€ theme
    β”‚   └── translation
    └── utils
  • app: will contain all our core app logic
    • components: will contain all the shared UI widgets
    • data: will contain our models and local data sources (local db & shared pref)
    • modules: app screens
    • routes: generated by get_cli and it will contain our navigation routes
    • services: contain all logic for making safe & clean api calls
  • config: will contain app config such as themes, localization services
  • utils: for our helper classes

Features

  • Theme: if you opened theme package you will see those files

    └── theme
        β”œβ”€β”€ dark_theme_colors.dart
        β”œβ”€β”€ light_theme_colors.dart
        β”œβ”€β”€ my_fonts.dart
        β”œβ”€β”€ my_styles.dart
        └── my_theme.dart
    
    

    you only need to change app colors (light/dark_theme_colors) and if you want to change app fonts sizes and family just modify my_fonts.dart and that is it you don't need to worry about styles and theme you only need to edit my_syles.dart if you want to change some element theme data (padding,border..etc) and if you want to change theme just use this code

    // change theme and save current theme state to shared pref
    MyTheme.changeTheme();

    and if you want to check if the theme is dark/light just use

    bool themeIsLight = MyTheme.getThemeIsLight();
    // OR
    bool themeIsLight = MySharedPref.getThemeIsLight();
  • Localization/translation we will use getx localization system which in the normal case code would look something like this

    class LocalizationService extends Translations {
        @override
        Map<String, Map<String, String>> get keys => {
            'en_US': { 'hello' : 'Hello' },
            'ar_AR': { 'hello' : 'Ω…Ψ±Ψ­Ψ¨Ψ§Ω‹' },
        };
    }
    
    Text('hello'.tr); // translated text 

    but because we have so many words to translate we will separate keys file (strings_enum.dart) and languages map into different classes so code will become like this

    class LocalizationService extends Translations {
          @override
          Map<String, Map<String, String>> get keys => {
              'en_US': enUs,
              'ar_AR': arAR,
          };
      }
    // keys
    class Strings {
        static const String hello = 'hello';
    }
    // english words
    const Map<String, String> enUs = {
        Strings.hello : 'Hello',
    }
    // arabic translate
    final Map<String, String> arAR = {
        Strings.hello : 'Ω…Ψ±Ψ­Ψ¨Ψ§',
    }
    //result
    Text(Strings.hello.tr)

    and that explain why we have this file structure inside our translation package

       └── translations
           β”œβ”€β”€ ar_Ar
           β”‚   └── ar_ar_translation.dart
           β”œβ”€β”€ en_US
           β”‚   └── en_us_translation.dart
           β”œβ”€β”€ localization_service.dart
           └── strings_enum.dart
    

    to change language you will use

    LocalizationService.updateLanguage('en');

    and to get the current locale/language you can use

    LocalizationService.getCurrentLocal();
    // OR
    MySharedPref.getCurrentLocal();
  • Safe api call: under if you opened lib/app/services package you will find 3 files

    • api_call_status.dart: which contain all possible stages of our api call (loading,success,error..etc)
    • api_exception.dart: custom exception class to make error handling more informative
    • base_client.dart: contain our safe api call functions to perform api request the right way you would do this
class HomeController extends GetxController {
  // hold data
  List<dynamic>? data;
  // api call status
  ApiCallStatus apiCallStatus = ApiCallStatus.holding;

  // getting data from api simulating
  getData() async {
    // *) indicate loading state
    apiCallStatus = ApiCallStatus.loading;
    update();
    // *) perform api call
    await BaseClient.get(
      Constants.todosApiUrl, // url
      onSuccess: (response){ // api done successfully
        data = List.from(response.data);
        // -) indicate success state
        apiCallStatus = ApiCallStatus.success;
        update(); // update ui
      },
      // if you don't pass this method base client
      // will automatically handle error and show message
      onError: (error){
        // show error message to user
        BaseClient.handleApiError(error);
        // -) indicate error status
        apiCallStatus = ApiCallStatus.error;
        update(); // update ui
      }, // error while performing request
    );
  }

  @override
  void onInit() {
    getData();
    super.onInit();
  }
}

base client will catch all the possible errors and if you didn't pass onError function it will automatically catch the error in UI side code will be

GetBuilder<HomeController>(
        builder: (_){
          return MyWidgetsAnimator(
              apiCallStatus: controller.apiCallStatus,
              loadingWidget: () => const Center(child: CircularProgressIndicator(),),
              errorWidget: ()=> const Center(child: Text('Something went wrong!'),),
              successWidget: () =>
                 ListView.separated(
                  itemCount: controller.data!.length,
                  separatorBuilder: (_,__) => SizedBox(height: 10.h,),
                  itemBuilder: (ctx,index) => ListTile(
                      title: Text(controller.data![index]['userId'].toString()),
                      subtitle: Text(controller.data![index]['title']),
                    ),
                ),

          );
        },
      )

NOTE: MyWidgetsAnimator will take care of ui changing with animation you will pass the ApiCallStatus and success,failed,loading..etc widgets and it will take care of transition

Support

For support, email [email protected] or Facebook Emad Beltaje.

You might also like...

A flutter package that helps you create an on-boarding screen for your project within minutes just by providing a few parameters.

A flutter package that helps you create an on-boarding screen for your project within minutes just by providing a few parameters.

A flutter package that helps you create an on-boarding screen for your project within minutes just by providing a few parameters.

Sep 27, 2022

Turkmen localization flutter - Support for turkmen localization in flutter

Localization for turkmen language Unfortunately, I didn't find any support for t

Nov 8, 2022

A basic boilerplate template for starting a Flutter GetX project. GetX, Dio, MVVM, get CLI, Localization, Pagination etc are implemented.

A basic boilerplate template for starting a Flutter GetX project. GetX, Dio, MVVM, get CLI, Localization, Pagination etc are implemented.

Flutter GetX Template (GetX, Dio, MVVM) This Flutter Template using GetX package for State management, routing and Dependency Injection (bindings). We

Jan 9, 2023

An online learning application with all needed features implemented

ELEARN An online learning application: completely functional with payment systems and firebase added. Overview This application has been developed to

Nov 4, 2021

Note provider - Note App using Provider state management, Sqflite and Localization for two language Arabic and English.

note_provider Sqflite with provider statemanagement Getting Started This project is a starting point for a Flutter application. A few resources to get

Jan 1, 2022

Call Kit is a prebuilt feature-rich call component, which enables you to build one-on-one and group voice/video calls into your app with only a few lines of code.

Call Kit is a prebuilt feature-rich call component, which enables you to build one-on-one and group voice/video calls into your app with only a few lines of code.

Call Kit (ZegoUIKitPrebuiltCall) Call Kit is a prebuilt feature-rich call component, which enables you to build one-on-one and group voice/video calls

Dec 26, 2022

A small app to manager simple transactions made in a shop (selling, buying, register handling..etc).

A small app to manager simple transactions made in a shop (selling, buying, register handling..etc).

Shop Manager Flutter A small app to manager simple transactions made in a shop (selling, buying, register handling..etc). Screenshot: Features: Detail

Dec 31, 2022

All the tools you need to build an app in 2 minutes

All the tools you need to build an app in 2 minutes. This is the main, standard CC Core. The plan is to make this into smaller, independent modules, but for now we are making it all available.

Dec 30, 2021

This is a university marketplace, where students buy and sell products and services online or offline. Mainly to connect the two parties together.

marktorder A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if th

Jan 10, 2022
Comments
  • changes on fcm_helper

    changes on fcm_helper

    Emad,

    take a look to this :

    https://github.com/firebase/flutterfire/issues/9446#issuecomment-1240554285

    it's a must for receiving notification while in background

    enhancement 
    opened by tva77 2
  • error when tapping notification with app terminated

    error when tapping notification with app terminated

    1- run terminal cmd flutter run --release

    2- terminated app; 3- sent fcm message; 4- received notification; 5- tapped notification; 6- app did not started and got error: [Awesome Notifications - ERROR]: onActionNotificationMethod is not a valid global or static method. (MethodChannelAwesomeNotifications:?)

    bug 
    opened by tva77 2
  • "pub finished with exit code 65" returns when I run command, is it was successful done?

    I run "flutter packages pub run build_runner build --delete-conflicting-outputs", then get result "pub finished with exit code 65". It means successfully done or error occurred?

    opened by yaruo-react-redux 1
Owner
Emad Beltaje
Emad Beltaje
Ahmed Elsayed 257 Jan 7, 2023
Awesome Notifications add-on plugin to enable push notifications through Firebase Cloud Messaging with all awesome notifications features.

Awesome Notifications FCM Awesome Notifications add-on to send push notifications using FCM (Firebase Cloud Messaging), with all awesome notifications

Rafael Setragni 8 Jan 4, 2023
Flutter Local Notifications - Learn how to implement local notifications into both Android and iOS using flutter_local_notifications plugin.

Flutter Local Notifications Example Flutter Local Notifications - Learn how to implement local notifications into both Android and iOS using flutter_l

Sandip Pramanik 12 Nov 29, 2022
A package help you to make api call and handle error faster, also you can check for internet before call api.

http_solver ##not for production use, only for learning purpose. A package help you to make api call and handle error faster, also you can check for i

Abdelrahman Saed 1 Jun 18, 2020
🌈 Repository for a compass project, basically an App for displaying bank transfers, with API requests, Flag persistence, Infinite Scroll, Error Handling, Unit Tests, Extract Sharing working with SOLID, BLoC and Designer Patterns.

?? Green Bank Aplicação desenvolvida em Flutter com intuito de trabalhar conexão com API, Gerenciamento de estado usando BLoC, Refatoração, Arquitetur

AndrΓ© Guerra Santos 28 Oct 7, 2022
A web-safe implementation of dart.io.Platforms. Helps avoid the "Unsupported operation: Platform._operatingSystem" runtime error.

Universal Platform - A Web-safe Platform class Currently, if you include the dart.io.Platform anywhere in your code, your app will throw the following

gskinner team 86 Nov 20, 2022
Flutter-Theme-Changer - Change theme of your app from light to dark theme and vice versa

Flutter Theme Changer - Hard Coded This is a flutter theme changer without using

Shametha K G 4 Oct 17, 2022
Flutter error catching & handling plugin. Handles and reports exceptions in your app!

Catcher Catcher is Flutter plugin which automatically catches error/exceptions and handle them. Catcher offers multiple way to handle errors. Catcher

Jakub 697 Jan 7, 2023
App HTTP Client is a wrapper around the HTTP library Dio to make network requests and error handling simpler, more predictable, and less verbose.

App HTTP Client App HTTP Client is a wrapper around the HTTP library Dio to make network requests and error handling simpler, more predictable, and le

Joanna May 44 Nov 1, 2022