Flutter MVVM Riverpod Starter

repository·main·Indexed 43 days ago

https://github.com/namanh11611/flutter_mvvm_riverpod

A lightweight Flutter starter template implementing MVVM architecture with Riverpod state management and a Supabase backend. It includes integrated features for authentication (Google, Apple, Magic Link), localization via easy_localization, monetization via RevenueCat, and a structured API client using Dio.

Tokens
7.9K
Snippets
27
Records
34
Agent score
55%

What's inside Flutter MVVM Riverpod Starter

  1. Understand the Project Structure

    main

    The project follows an MVVM (Model-View-ViewModel) architecture organized by feature modules. The directory structure is as follows:

    • lib/constants/: App constants and configurations.
    • lib/environment/: Environment variables and configuration files.
    • lib/extensions/: Extension methods and helpers.
    • lib/features/: Feature-based modules (e.g., authentication, home, profile, premium).
    • lib/routing/: Route configurations (using go_router).
    • lib/theme/: Theme configurations (Dark/Light support).
    • lib/utils/: Utility functions.
  2. Customize the iOS Launch Screen assets

    main

    To change the launch screen image for the iOS version of this Flutter project, you can either replace the image files directly in the ios/Runner/Assets.xcassets/LaunchImage.imageset/ directory or use Xcode.

    Using Xcode:

    1. Open the iOS project in Xcode by running open ios/Runner.xcworkspace from your terminal.
    2. In the Xcode Project Navigator, navigate to Runner/Assets.xcassets.
    3. Drag and drop your desired images into the asset catalog to replace the existing launch screen assets.
    open ios/Runner.xcworkspace
  3. Get Started with Flutter MVVM Riverpod Starter

    main

    Follow these steps to set up the project locally and prepare it for development:

    1. Clone the repository:
      git clone https://github.com/namanh11611/flutter_mvvm_riverpod.git
    2. Install dependencies:
      flutter pub get
    3. Generate localization files (using easy_localization):
      dart run easy_localization:generate -f keys -o locale_keys.g.dart --source-dir assets/translations
    4. Generate code (using build_runner for Riverpod annotations and other generators):
      dart run build_runner build --delete-conflicting-outputs
    5. Run the app:
      flutter run
    git clone https://github.com/namanh11611/flutter_mvvm_riverpod.git
    flutter pub get
    dart run easy_localization:generate -f keys -o locale_keys.g.dart --source-dir assets/translations
    dart run build_runner build --delete-conflicting-outputs
    flutter run
  4. Configure App Identity and Package Names

    main

    To customize the application's identity, perform the following steps:

    Change Package Name

    Use the change_app_package_name tool to update the Android and iOS package identifiers:

    dart run change_app_package_name:main com.new.package.name

    Change Android App Name

    Open android/app/src/main/AndroidManifest.xml and update the android:label attribute:

    android:label="New App Name"

    Change iOS App Name and Bundle Name

    Open ios/Runner/Info.plist and update the following keys:

    • Display Name: Change CFBundleDisplayName to New App Name.
    • Bundle Name: Change CFBundleName to new_bundle_name.
  5. Use Nunito Variable or Static fonts

    main

    The assets/google_fonts/ directory provides the Nunito font family in two formats: Variable fonts and Static fonts.

    Variable Fonts

    If your application supports variable fonts, use the following files to access intermediate styles via the wght axis:

    • Nunito-VariableFont_wght.ttf
    • Nunito-Italic-VariableFont_wght.ttf

    Static Fonts

    If your application does not support variable fonts, use the individual files located in the static/ directory:

    • static/Nunito-ExtraLight.ttf
    • static/Nunito-Light.ttf
    • static/Nunito-Regular.ttf
    • static/Nunito-Medium.ttf
    • static/Nunito-SemiBold.ttf
    • static/Nunito-Bold.ttf
    • static/Nunito-ExtraBold.ttf
    • static/Nunito-Black.ttf
    • static/Nunito-ExtraLightItalic.ttf
    • static/Nunito-LightItalic.ttf
    • static/Nunito-Italic.ttf
    • static/Nunito-MediumItalic.ttf
    • static/Nunito-SemiBoldItalic.ttf
    • static/Nunito-BoldItalic.ttf
    • static/Nunito-ExtraBoldItalic.ttf
    • static/Nunito-BlackItalic.ttf
  6. Initialize the application entry point

    main

    The application is initialized in the main() function. It performs several asynchronous setup steps including Supabase initialization, localization setup, and license registration. The entire application is wrapped in a ProviderScope to enable Riverpod state management, with an AppObserver attached to monitor provider changes.

    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
    
      /// Supabase
      await Supabase.initialize(
        url: Env.supabaseUrl,
        anonKey: Env.supabaseAnonKey,
      );
    
      /// Localization
      await EasyLocalization.ensureInitialized();
    
      /// Google Font
      LicenseRegistry.addLicense(() async* {
        final license = await rootBundle.loadString('google_fonts/OFL.txt');
        yield LicenseEntryWithLineBreaks(['google_fonts'], license);
      });
    
      runApp(
        ProviderScope(
          observers: [AppObserver()],
          child: EasyLocalization(
            supportedLocales: const [Locale('en'), Locale('vi')],
            path: 'assets/translations',
            fallbackLocale: const Locale('en'),
            useOnlyLangCode: true,
            child: const MainApp(),
          ),
        ),
      );
    }
  7. Configure Windows application metadata and icon

    main

    The windows/runner/Runner.rc file is a Microsoft Visual C++ resource script used to define the Windows-specific metadata and assets for the application. You can modify this file to change the application's icon, version information, and descriptive metadata (like Company Name or File Description) that appears in Windows File Explorer.

    /////////////////////////////////////////////////////////////////////////////
    //
    // Icon
    //
    IDI_APP_ICON            ICON                    "resources\\app_icon.ico"
    
    /////////////////////////////////////////////////////////////////////////////
    //
    // Version
    //
    VS_VERSION_INFO VERSIONINFO
     FILEVERSION VERSION_AS_NUMBER
     PRODUCTVERSION VERSION_AS_NUMBER
    // ...
        BLOCK "StringFileInfo"
        BEGIN
            BLOCK "040904e4"
            BEGIN
                VALUE "CompanyName", "com.henry" "\0"
                VALUE "FileDescription", "flutter_mvvm_riverpod" "\0"
                VALUE "FileVersion", VERSION_AS_STRING "\0"
                VALUE "InternalName", "flutter_mvvm_riverpod" "\0"
                VALUE "LegalCopyright", "Copyright (C) 2024 com.henry. All rights reserved." "\0"
                VALUE "OriginalFilename", "flutter_mvvm_riverpod.exe" "\0"
                VALUE "ProductName", "flutter_mvvm_riverpod" "\0"
                VALUE "ProductVersion", VERSION_AS_STRING "\0"
            END
        END
  8. Reference of Libraries and Tools used

    main

    This starter template integrates the following libraries for various functionalities:

    CategoryLibraryPurpose
    State Managementflutter_riverpod, riverpod_annotationReactive state management and code generation
    Backend & Authsupabase_flutter, google_sign_in, sign_in_with_appleBackend as a service and social authentication
    Navigationgo_routerDeclarative routing
    Storageshared_preferences, sqfliteLocal key-value and database storage
    Networkdio, connectivity_plusHTTP client and network connectivity monitoring
    UI/UXgoogle_fonts, flutter_svg, shimmer, lottieFonts, SVGs, and animations
    Utilitieseasy_localization, envied, uuidInternationalization, env vars, and unique IDs
    Analyticsfirebase_analytics, firebase_crashlyticsUsage tracking and crash reporting
    Monetizationin_app_purchase, purchases_flutterIn-app purchases and RevenueCat integration
  9. Review Nunito font license

    main

    The Nunito fonts are provided under the Open Font License (OFL). You can use them in print or digital products, commercial or otherwise.

    Important: You must read the full license text (OFL.txt) to understand the specific permissions, restrictions, and requirements for usage, redistribution, and modification. This summary does not constitute legal advice.

  10. Perform GET and POST requests with ApiClient

    main

    The ApiClient provides high-level methods for making network requests. Both methods automatically handle error mapping and return the parsed response data of type T.

    get<T>(String path, {Map<String, dynamic>? queryParameters, Options? options})

    Performs a GET request to the specified path. Use queryParameters to append URL parameters.

    post<T>(String path, {dynamic data, Map<String, dynamic>? queryParameters, Options? options})

    Performs a POST request to the specified path. Use data to send the request body.

    // Example GET request
    final user = await apiClient.get<User>('/user/123');
    
    // Example POST request
    final newUser = await apiClient.post<User>('/user', data: {'name': 'John Doe'});
  11. Use AuthenticationViewModel methods for authentication tasks

    main

    The AuthenticationViewModel provides the following public methods for controlling authentication logic:

    MethodParametersDescription
    signInWithMagicLinkString emailInitiates sign-in via a magic link sent to the provided email.
    verifyOtpString email, String token, bool isRegisterVerifies a One-Time Password (OTP) for registration or sign-in.
    signInWithGoogleNoneTriggers Google OAuth sign-in.
    signInWithAppleNoneTriggers Apple OAuth sign-in.
    signOutNoneLogs the user out of the current session.
    updateProfileUser userUpdates the user's profile information (name, avatar) in the profileViewModelProvider.
    isLoginNoneReturns a Future<bool> indicating if the user is currently logged in.
    isGuestModeNoneReturns a Future<bool> indicating if the app is in guest mode.
    setIsGuestModeNoneSets the application to guest mode.