Coder Social home page Coder Social logo

kenaragorn / create_flutter_provider_app Goto Github PK

View Code? Open in Web Editor NEW
397.0 21.0 120.0 1.9 MB

A boilerplate project created in Flutter using Provider and Firebase.

License: MIT License

Kotlin 0.63% Swift 0.60% Objective-C 0.06% Dart 98.72%
flutter dart boilerplate boilerplate-template flutter-boilerplate provider state-management flutter-state-management flutter-examples flutter-demo

create_flutter_provider_app's Introduction

Flutter Boilerplate Project using Provider with Firebase Authentication and Firestore

This is the boilerplate project for anyone that want to create Flutter mobile application using Provider, Shared Preferences and Firebase.

Motivation

The project contains the minimal implementation required to create a new Flutter project using Provider for state management and Firebase as the backend connectivity for user authorisation control and Firestore for database.

The project come with preloaded folder structure recommended for Provider and separation of business logic, user interface and services needed for any Flutter Firebase project. Apart from that, it come with commonly used files and widgets such as app theme, constants and common Firebase code.

Instead of spending time in every new project to setup development structure, copy and paste, this will help in reducing the common code practise and structure, and quickly allow us to focus on the core part of the app, avoiding writing again and again the same code from scratch.

Project Goals

The main goal is to define a reference architecture that can be used as the foundation for Flutter app that require the usage of Firebase and eventually:

  • To reduce developer time in re-writing common code and project structure from scratch
  • To have a common folder and package structure that can be further extended should it require
  • Clearing define the app layer – UI layer, business logic layer and service layer

The 3 main layers:

  • UI layer – all UI widgets files
  • Business logic layer – contains all app business and presentation logic
  • Service layer – contains services needed to interact with between the app and 3rd party services such as APIs

This project bundled with a demo app as a practical example of this architecture.

Demo App: Todo App

The demo app demonstrates a simple but comprehensive enough to capture the various challenges and use cases of state management across multiple screens and different modules.

After signed into the app, users can view, create, edit and delete their todo notes. User can change the theme and data is stored in Firebase Firestore.

How to Use

Step 1:

Download or clone this repo by using the following link: https://github.com/KenAragorn/create_flutter_provider_app.git

Step 2:

Go to your local extracted clone copy of the project, open the android/build.gradle file and change the applicationId to your own application ID. For example, com.your_com_name.project_name.

Step 3:

Go to the project root and execute the following command to get all dependencies packages: flutter pub get

Step 4:

Go to your Firebase console. Create a new Firebase project. Once created without any issue, register your app by clicking the icon – for Android, click on the Android icon and for iOS, click on the iOS icon. Complete the rest of the step require.

Step 5:

Ensure the Android package name is the same value as your application ID setup in step 2.

Step 6:

Download the google-services.json file provided by Firebase to the android/app directory. Then, update the Gradle build files under android/build.gradle to register the app with Google services.

Step 7:

Update the android/app/build.gradle file by adding the following highlighted code:

Step 8:

Go back to your Firebase console to create the database Cloud Firestore. Choose the test mode option. You can change it later, just make sure to choose the nearer Cloud Firestore location nearer to your location.

Step 9:

Still within Fiebase console, go to Authentication and turn on the sign-in method. In our case, that would be email/password have to turn on by setting the status to enabled. Other sign-in method will be added soon.

Step 10:

Done. Try launch the app using emulator or your preferred physical test device. For first time user, you need to create a new account from the app.

Third Party Libraries Dependencies:

Project Key Features:

  • Splash Screen
  • New User Registration & Login - Firebase Auth - Email/Password only (more will be added soon)
  • Routing – Separation of routing files for ease of maintenance
  • Theme – Separation of theme files that support dark and light theme
  • Provider – State management
  • Caching – Using SharedPreferences to keep track theme selection
  • Internationalization – Newly added - 11 April 2020
  • Multiple Build Environment – Using multiple Flavors to connect 2 different Firebase environment - Dev and Production Newly added - 23 April 2020

Folder Structure:

lib/
|- constants/ – contains all application level constants for theme, font types and app strings.
|- caches/ – contains data layer such as shared preferences.
|- models/ – contains all the plain data models.
|- services/ – contains all services files that handle the API calling for CRUD related functionalities.
|- providers/ – contains all Provider models for each of the widget views.
|- ui/ the main folder that will contains all UI related breaking down further by different modules (such as authentication, home, etc) and sub section (reusable widgets and screens).
|- routes.dart
|- app_localizations.dart
|- auth_widget_builder.dart
|- flavor.dart - main class for handling the multiple build - dev and production
|- my_app.dart
|- main.dart - the main.dart file for dev environment (means, connecting to Firebase Cloud Database Dev)
|- main_prod.dart - the main.dart for production environment (means, connecting to Firebase Cloud Database Production)

What inside constants?

Basically, all needed constant files for the application to work will be here.

constants/
|- app_themes.dart – the theme file for the app
|- app_font_family.dart – the app global supported font family

What inside cache?

As of now, only shared preferences files. In future we may have others such as sqlite features and it is good to keep things separated.

caches/
|- sharedpref/shared_preference_helper.dart

What inside models?

All plain data models file will be here. Depending on the number of the model files, if it is more than 10 files, we suggest separating the files by sub folder such as models/auth, models/todo etc. Else, keep it simple with every data model file is within this folder.

models/
|- user_model.dart
|- todo_model.dart

What inside services?

As we have backend firestore and firebase for application data such as user and todo data, we will need a dart classes that represent the CRUD services to handle any communication between the UI code and the backend.

services/
|- firestore_database.dart
|- firestore_service.dart
|- firestore_path.dart

What inside providers?

Contains all provider models needed for the app. The idea is like those in models and services in which, different provider class will be created for different key modules.

providers/
|- auth_provider.dart
|- theme_provider.dart

What inside UI?

This directory contains all the UI files for the application. As most of the times, there will be more than 1 files representing a screen, thus is always good to separate it by sub-folder and grouping it based on their key features or modules.

ui/
|- auth
        |- register_screen.dart
        |- sign_in_screen.dart
|- splash
        |- splash_screen.dart
|- home
        |- home.dart
|- todo
        |- todos_screen.dart
        |- create_edit_todo_screen.dart

Use Case: Firestore Service

Any widgets module can subsribe to updates from Firebase Firestore through streams, as well as write operation such as creation and deletion of data using Future-based APIs.

For convenient, all Firestore related CRUD services for the demo app is all in 1 place:

class FirestoreDatabase { // implementation omitted for brevity
  Future<void> setTodo(TodoModel todo); // create / update
  Future<void> deleteTodo(TodoModel todo); // delete
  Stream<List<TodoModel>> todosStream(); // read
  Stream<Job> todoStream({@required String todoId}); // read
}

With this setup, creating a widget that shows a list of jobs becomes simple:

@override
Widget build(BuildContext context) {
  final database = Provider.of<FirestoreDatabase>(context, listen: false);
  return StreamBuilder<List<Job>>(
    stream: database.todosStream(),
    builder: (context, snapshot) {
      // TODO: return widget based on snapshot
    },
  );
}

Domain-level model classes are defined, along with fromMap() and toMap() methods for serialization.

Note about stream-dependant services

When using Firestore, is quite common to organise user data inside documents or collections that depend on the unique user uid.

When reading or writing data, the app need to access to the user uid. This can change at runtime, as user can log out and sign back in with a different account, which eventually a different uid.

This, the FirestoreDatabase takes the uid as a constructor parameter. So, the moment we have FirebaseUser upon user logged in, we can just pass the uid to the Firestore database when performing CRUD operations.

To achieve this, FirestoreDatabase will be re-created everytime onAuthStateChanged changed.

Use Case: Internationalization

Added Internationalization features to the project. The example contains 2 languages namely English and Chinese.

With this, the sample app now contains feature that allow user to change language from English to Chinese and vice-versa.

This feature is added at Setting page - concept works the same as theme.

There are 2 JSON files that contains key-value pairs of strings for English and Chinese.

This 2 files is located at new folder called lang under the project root folder.

lang/
|- en.json
|- zh.json

By using JSON, it will be easier to manage as you can give it to translator to translate the words without needing them to access the code.

The pubspec.yaml is updated to include dependency for flutter_localizations. Also, added the asset reference for the new folder lang.

Below are the steps require to add for additional languages.

  1. Create a new JSON file for the new language file. For example, sk.json for Slovak.
  2. Copy the content of en.json/zh.json to the new json file.
  3. Pass the new JSON file to translator or do it yourself and update the word to the right word.
  4. Update the main.dart to include the additional supported locales for the additional language. Inside main.dart:
supportedLocales: [
Locale('en', 'US'), 
Locale('zh', 'CN'),
Locale('sk', 'SK')  //example, if you add the Slovakian language 
],
  1. Update the app_localizations.dart to include additional supported locales for the additional language:
  @override
  bool isSupported(Locale locale) {
    // Include all of your supported language codes here
    return ['en', 'zh', 'sk'].contains(locale.languageCode);
  }
  1. Take note, if you prefer the app to be responsive to the phone actual locale setting and do not allow the app to contain any feature to change the language display, then you need to comment out the code at main.dart:
  return MaterialApp(
      debugShowCheckedModeBanner: false,
      locale: languageProviderRef.appLocale,   // <-- comment out this code

By comment out the code locale: languageProviderRef.appLocale, the app will response only to the system locale setting. For example:

Use Case: Multiple Build Environment – Using multiple Flavors

Added configurations and further enhanced the project structure with new codes to handle multiple build environment.

It is always a good practise to build separate apps from the same source code and for different environment such as development, staging and production.

In this latest update, we added 2 build environment namely development and production.

Below are the steps for existing developers that used the older code and what need to be done to make your local project to have multiple build.

  1. Create 2 Different Firebase Projects and Configuration

For this, as mentioned earlier, we will be defining 2 environments namely development and production, so we will need to create 2 Firebase projects. Then, for each Firebase projects, create a Cloud Firestore database. Do remember to have at least 1 sign-in method enabled for both projects – for this example, we are using Email/Password only. Next, we need to get the google-services.json for each Firebase project.

To do that, lets assume we will be using the following applicationId for both environment:

  • Note App Prod – applicationId: com.example.create_flutter_provider_app.prod
  • Note App Dev - applicationId: com.example.create_flutter_provider_app.dev

You can use your preference naming convention for the applicationId, as long it is understandable that 1 is for production environment and another is for development environment. With the applicationId defined, we will used it to add Firebase to our project. Go to each Firebase project, click on the small Android icon and the following screen will appear. Add the applicationId to the right Firebase project as specified above.

Once registering the app, download the google-services.json for each Firebase projects.

  1. Updating Project Config Files Add in the following configuration into the project android/app/build.gradle:
    flavorDimensions "flavor-type"

    productFlavors {
        dev {
            dimension "flavor-type"
            applicationId "com.example.create_flutter_provider_app.dev"
            versionCode 1
            versionName "1.0"
        }
        prod{
            dimension "flavor-type"
            applicationId "com.example.create_flutter_provider_app.prod"
            versionCode 1
            versionName "1.0"
        }
    }

An example:

  1. Create 2 folders Representing Development and Production

The folder name must match the named specified in productFlavors (android/app/build.gradle). The previous downloaded google-services.json files for both Firebase projects need to be moved to the right folder. For the file downloaded from Note App Prod, place it under the folder prod and for the same file name downloaded from Note App Dev, place it under the dev folder. For the sub folder called ‘res’, ignore it for now. We will go through that shortly.

  1. Having different app name and app icon for Dev and Prod We want to have a different app name for our project. This is helpful as with Flavor setup, we can install both app in the same devices for testing. Having app name such as NoteApp-Dev or Note-Dev or Note-Prod helps us to identify which app is for which environment – development or production. The same concept and benefits if we have different app icon for each apps that are connecting to different environment. For app name, create file called strings.xml and with the following content:
<?xml version="1.0" encoding="utf-8"?>
<resources>
        <string name="app_name">Note-Dev</string>
</resources>

Change the app_name to fit your Dev app. Put this file under the dev/res/values:

Do the same for the prod environment but name your app_name to be Note-Prod or something that represent it is the app for Production.

<?xml version="1.0" encoding="utf-8"?>
<resources>
        <string name="app_name">Note-Prod</string>
</resources>

The final step for the app name is to change the Android manifest file to refer to the String name app_name. To do that, open the file AndroidManifest.xml located at android/app/src/main folder. Update the android:label as follow:

android:label="@string/app_name"

Next, for the images, copied all 5 sub folders that start with the name mipmap-xxx from main/res/, and paste it to the res folder for both dev and prod. At the end, you should have the following view:

If you notice, each sub-folder with the name minimap contains images and that image is the app icon image. Change it to your needs.

  1. New Dart files and Code Updates Create a flavour.dart file. This will just contain enum value that represent both dev and prod environment that the main class can refer and decide. The code:
enum Flavor {dev, prod}

Since we are using the Flutter template shared above, we will need to create additional main.dart that represent the production build and using the original main.dart to be representing as development build. Our goal is to able to build and run different flavor as follow:

flutter run --flavor dev -t lib/main.dart
flutter run --flavor prod -t lib/main_prod.dart

First, update the main.dart as follow:

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
      .then((_) async {
    runApp(
      MultiProvider(
        providers: [
          Provider<Flavor>.value(value: Flavor.dev),
          ChangeNotifierProvider<ThemeProvider>(
            create: (context) => ThemeProvider(),
          ),
          ChangeNotifierProvider<AuthProvider>(
            create: (context) => AuthProvider(),
          ),
          ChangeNotifierProvider<LanguageProvider>(
            create: (context) => LanguageProvider(),
          ),
        ],
        child: MyApp(
          databaseBuilder: (_, uid) => FirestoreDatabase(uid: uid),
        ),
      ),
    );
  });
}

As mentioned before, we will make the main.dart as the representative of building a development build. As this project is using Provider, we will pre-set the main.dart to use the dev flavor. Duplicate this file and renamed it as main_prod.dart. Update the Flavor.dev to Flavor.prod. Then, apart from the previous app name and app icon changes, we felt it is also necessary to display some info at the first screen namely the sign-in screen. Thus, since we are using Provider to set the initial value of the both main.dart and main_prod.dart, we then can access this initial default value at the sign-in screen as follow:

Text(
  Provider.of<Flavor>(context).toString(),
),

So, what will happen if we were to run the following code:

flutter run --flavor dev -t lib/main.dart

Flutter will try to build and run the app using the flavor dev and using the main.dart file. This will result the following display of sign-in screen:

Notice the bottom part, it contains the value of the enum value dev.

The command: flutter run --flavor dev -t lib/main.dart is basically telling Flutter to build the app for testing using the flavour dev specified in the build.gradle. Also, the second part is basically telling it to run it using main.dart file. And since our main.dart has the initial flavor value pre-set as dev, it will be display as Flavor.dev. If were to run the command: flutter run --flavor prod -t lib/main_prod.dart, will result the following:

Notice the bottom of the screen, it is displaying Flavor.prod.

Future Roadmap

  • Additional Sign-in method - Google
  • Animation
  • Separation of different build flavors
  • Internationalization

Conclusion

Again, take note, this is an example from my few mobile app projects, and instead of repeating the same process over and over again, I decided to spend some time to create this architecture that is easier to onboard for any new Flutter project that used Provider and Firebase. If you liked my work, don’t forget to ⭐ star the repo to show your support.

create_flutter_provider_app's People

Contributors

ahmadalibaloch avatar kenaragorn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

create_flutter_provider_app's Issues

App state for SignIn Screen

It seems that the 'userSnapshot.hasData' function is always returning true and the 'SignIn' screen is not called on line 80 of the 'my_app.dart' file. I'm new with flutter, I'm still understanding the use of the 'Provider' approach.

Firebase / initializeApp()

Hello,

First of all, thank you for the code, it can have a lot of value.

That being said, I found some issues when trying to start the app.

First I had to go to pubspec.yaml and do:

  assets:
    - assets/lang/en.json
    - assets/lang/zh.json
 
  fonts:
    - family: ProductSans
      fonts:
        - asset: assets/fonts/Product-Sans-Regular.ttf
        - asset: assets/fonts/Product-Sans-Italic.ttf
          style: italic
        - asset: assets/fonts/Product-Sans-Bold.ttf
          weight: 700
        - asset: assets/fonts/Product-Sans-Bold-Italic.ttf
          style: italic
          weight: 700

and change line 27 on the app_localizations.dart to

await rootBundle.loadString('assets/lang/${locale.languageCode}.json');

or the app wouldn't even start.

Then I had to add

await Firebase.initializeApp();

between lines 15/16 of the main.dart and main_prod.dart, or again, the app wouldn't even start. (Also had to add firebase_core: ^1.6.0 to the pubspec.yaml, and the import to main.dart and and main_prod.dart of course).

Then in line 81 of the my_app.dart I had to change it to:

return userSnapshot.data?.uid != 'null'
  ? HomeScreen()
  : SignInScreen();

because userSnapshot.hasData always had "something", and that was causing records to be inserted in the database with uid as null meaning /user/null/todos/<todo_item_id>.

But now I can't move on.

The issue itself is when I log out and login with another user, I have the data from the old user.

I know you say on the README.md that:

To achieve this, FirestoreDatabase will be re-created everytime onAuthStateChanged changed.

But this doesn't seem to be happening.

Might be due to my changes as mentioned above.

Any help would be much appreciated. Regards to all.

Reflect Real Time Change from Database

Hi Ken,
Thank you for making this. This is a not an issue but rather a question:
I am building a Chat App with Flutter and FireStore. At first I just stream the data directly to Stream Builder and store reusable data like user data in Shared Preferences, but this might cause a lot of calls to the database for non-reusable data. So I search and find out about using provider with Firestore and find your project. My question is, if using Provider, can the data reflect changes in real time if there are changes in the database, like if an user change their name and all people in their friend list can see the changed name? Or in a chat group, if someone send a message, will other see them also or do they have to refresh the data? I know it might not related too much to the project but I am planning on scrapping my current one and use your as a template to build it if it match the above critia.

App crash after build: FATAL EXCEPTION: main - java.lang.RuntimeException: Unable to instantiate activity - java.lang.ClassNotFoundException: Didn't find class "com.NAME.APPNAME.MainActivity" on path: DexPathList

I took me way to long to fix this error, so I hope this helps someone else:
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.NAME.APPNAME.dev/com.NAME.APPNAME.MainActivity}: java.lang.ClassNotFoundException: Didn't find class "com.NAME.APPNAME.MainActivity" on path: DexPathList[[zip file "/data/app/com.NAME.APPNAME.dev-XzP2FDlcF7ok_QeihJlBQQ==/base.apk"],nativeLibraryDirectories=[/data/app/com.NAME.APPNAME.dev-XzP2FDlcF7ok_QeihJlBQQ==/lib/x86, /data/app/com.NAME.APPNAME.dev-XzP2FDlcF7ok_QeihJlBQQ==/base.apk!/lib/x86, /system/lib]]

Maybe this error came because I renamed the bundle itentifier in the AndroidManifest files and everywhere else I could find it. This step wasn´t explicitly explained in the setup of the project.

My solution in the end was to also rename the "android/app/src/main/kotlin/com/venturearkstudio/noteapp" folder structure into my bundle identifier ".../com/NAME/APPNAME". And then also in the MainActivity.kt file the "package com.venturearkstudio.noteapp" to "package com.NAME/APPNAME".

Not sure if these steps should be added into the setup instructions or if I made something wrong and then ran into this issue.

lang/ asset not found

Hi,

I keep getting this error:

image

I have tried to add it in the pubspec file under :

flutter:
   assets:
   - lang/
   // And - assets/lang

any idea what I need to add also?

Firebase changes

Hi Ken

Any plans to apply the changes required for the latest Firebase updates?

Thanks
Bigtaff

Storage service

Excellent code. How would you implement the storage service?

How to manage user settings from firebase ?

Hi,

In this architecture if we wanted to have global parameters for a specific user, stored in firebase, how would you do it?

Make another widget / stream + provider like widgetAuthBuilder, below this one? Or is there a better way? Overload the "flat" user from firebase ?

I'm a little lost, if you can clarify this :)

Thanks

Dependency issue upon running flutter pub get: firebase_auth requires firebase_auth_web

I wanted to test out this project but upon trying to run flutter pub get I receive a long list of dependency issues related to firebase_auth_web. I tried adding the version of firebase_auth_web it requested but that led to further dependency issues.

Log:

PS C:\Users\eric1\OneDrive\Desktop\Flutter\create_flutter_provider_app> flutter pub get
Resolving dependencies... (2.7s)
    Because firebase_auth >=3.2.0 <3.3.0 depends on firebase_auth_web ^3.2.0 and firebase_auth >=3.3.0 <3.3.1 depends on firebase_auth_web ^3.3.0, firebase_auth
      >=3.2.0 <3.3.1 requires firebase_auth_web ^3.2.0.
    And because firebase_auth >=3.3.1 <3.3.2 depends on firebase_auth_web ^3.3.2 and firebase_auth >=3.3.2 <3.3.3 depends on firebase_auth_web ^3.3.3, firebase_auth
      >=3.2.0 <3.3.3 requires firebase_auth_web ^3.2.0.
    And because firebase_auth >=3.3.3 <3.3.4 depends on firebase_auth_web ^3.3.4 and firebase_auth >=3.3.4 <3.3.5 depends on firebase_auth_web ^3.3.5, firebase_auth
      >=3.2.0 <3.3.5 requires firebase_auth_web ^3.2.0.
    And because firebase_auth >=3.3.5 <3.3.6 depends on firebase_auth_web ^3.3.6 and firebase_auth >=3.3.6 <3.3.8 depends on firebase_auth_web ^3.3.7, firebase_auth
      >=3.2.0 <3.3.8 requires firebase_auth_web ^3.2.0.
    And because firebase_auth >=3.3.8 <3.3.9 depends on firebase_auth_web ^3.3.8 and firebase_auth >=3.3.9 <3.3.12 depends on firebase_auth_web ^3.3.9, firebase_auth
      >=3.2.0 <3.3.12 requires firebase_auth_web ^3.2.0.
    And because firebase_auth >=3.3.12 <3.3.13 depends on firebase_auth_web ^3.3.10 and firebase_auth >=3.3.13 <3.3.14 depends on firebase_auth_web ^3.3.11,
      firebase_auth >=3.2.0 <3.3.14 requires firebase_auth_web ^3.2.0.
    And because firebase_auth >=3.3.14 <3.3.15 depends on firebase_auth_web ^3.3.12 and firebase_auth >=3.3.15 <3.3.17 depends on firebase_auth_web ^3.3.13,
      firebase_auth >=3.2.0 <3.3.17 requires firebase_auth_web ^3.2.0.
    And because firebase_auth >=3.3.17 <3.3.18 depends on firebase_auth_web ^3.3.14 and firebase_auth >=3.3.18 <3.3.19 depends on firebase_auth_web ^3.3.15,
      firebase_auth >=3.2.0 <3.3.19 requires firebase_auth_web ^3.2.0.
    And because firebase_auth >=3.3.19 <3.3.20 depends on firebase_auth_web ^3.3.16 and firebase_auth >=3.3.20 <3.4.0 depends on firebase_auth_web ^3.3.17,
      firebase_auth >=3.2.0 <3.4.0 requires firebase_auth_web ^3.2.0.
    And because firebase_auth >=3.4.0 <3.4.1 depends on firebase_auth_web ^3.3.18 and firebase_auth >=3.4.1 <3.4.2 depends on firebase_auth_web ^3.3.19, firebase_auth
      >=3.2.0 <3.4.2 requires firebase_auth_web ^3.2.0.
    And because firebase_auth >=3.4.2 <3.5.0 depends on firebase_auth_web ^4.0.0 and firebase_auth >=3.5.0 <3.5.1 depends on firebase_auth_web ^4.1.0, firebase_auth
      >=3.2.0 <3.5.1 requires firebase_auth_web ^3.2.0 or >=4.0.0 <5.0.0.
    And because firebase_auth >=3.5.1 <3.6.0 depends on firebase_auth_web ^4.1.1 and firebase_auth >=3.6.0 <3.6.1 depends on firebase_auth_web ^4.2.0, firebase_auth
      >=3.2.0 <3.6.1 requires firebase_auth_web ^3.2.0 or >=4.0.0 <5.0.0.
    And because firebase_auth >=3.6.1 <3.6.2 depends on firebase_auth_web ^4.2.1 and firebase_auth >=3.6.2 <3.6.3 depends on firebase_auth_web ^4.2.2, firebase_auth
      >=3.2.0 <3.6.3 requires firebase_auth_web ^3.2.0 or >=4.0.0 <5.0.0.
    And because firebase_auth >=3.6.3 <3.6.4 depends on firebase_auth_web ^4.2.3 and firebase_auth >=3.6.4 <3.7.0 depends on firebase_auth_web ^4.2.4, firebase_auth
      >=3.2.0 <3.7.0 requires firebase_auth_web ^3.2.0 or >=4.0.0 <5.0.0.
    And because firebase_auth >=3.7.0 <3.8.0 depends on firebase_auth_web ^4.3.0 and firebase_auth >=3.8.0 <3.9.0 depends on firebase_auth_web ^4.4.0, firebase_auth
      >=3.2.0 <3.9.0 requires firebase_auth_web ^3.2.0 or >=4.0.0 <5.0.0.
    And because firebase_auth >=3.9.0 <3.10.0 depends on firebase_auth_web ^4.4.1 and firebase_auth >=3.10.0 <3.11.0 depends on firebase_auth_web ^4.5.0,
      firebase_auth >=3.2.0 <3.11.0 requires firebase_auth_web ^3.2.0 or >=4.0.0 <5.0.0.
(1) So, because firebase_auth >=3.11.0 <3.11.2 depends on firebase_auth_web ^4.6.0 and firebase_auth ^3.11.2 depends on firebase_auth_web ^4.6.1, firebase_auth ^3.2.0
      requires firebase_auth_web ^3.2.0 or >=4.0.0 <5.0.0.

    Because firebase_auth >=3.1.5 <3.2.0 depends on firebase_auth_web ^3.1.4 and firebase_auth >=3.1.4 <3.1.5 depends on firebase_auth_web ^3.1.3, firebase_auth
      >=3.1.4 <3.2.0 requires firebase_auth_web ^3.1.3.
    And because firebase_auth >=3.1.3 <3.1.4 depends on firebase_auth_web ^3.1.2 and firebase_auth >=3.1.0 <3.1.2 depends on firebase_auth_web ^3.1.0, firebase_auth
      >=3.1.0 <3.1.2-∞ or >=3.1.3 <3.2.0-∞ requires firebase_auth_web ^3.1.0.
    And because no versions of firebase_auth match >3.0.2 <3.1.0 and firebase_auth >=3.1.2 <3.1.3 depends on firebase_auth_web ^3.1.1, firebase_auth >3.0.2 <3.2.0
      requires firebase_auth_web ^3.1.0.
    And because firebase_auth ^3.2.0 requires firebase_auth_web ^3.2.0 or >=4.0.0 <5.0.0 (1), firebase_auth >3.0.2 <4.0.0 requires firebase_auth_web >=3.1.0 <4.0.0 or
      >=4.0.0 <5.0.0.
    And because firebase_auth 3.0.2 depends on firebase_auth_web ^3.0.1, firebase_auth ^3.0.2 requires firebase_auth_web >=3.0.1 <4.0.0 or >=4.0.0 <5.0.0.
    And because firebase_auth_web >=1.0.0 <5.2.2 depends on intl ^0.17.0 and every version of flutter_localizations from sdk depends on intl 0.18.0, firebase_auth
      ^3.0.2 is incompatible with flutter_localizations from sdk.
    So, because noteapp depends on both flutter_localizations from sdk and firebase_auth ^3.0.2, version solving failed.
PS C:\Users\eric1\OneDrive\Desktop\Flutter\create_flutter_provider_app> 

Question: where does uid come from?

Thought there was a lot of good stuff in this repo. I've been looking at this one line for a while and curious how it works. You stopped just short of explaining this in your medium article.

In this line databaseBuilder: (_, uid) => FirestoreDatabase(uid: uid), I understand that FirestoreDatabase takes a named parameter called uid, and that the value for that is coming from (_, uid). What I'm not following is where the uid for (_, uid) is actually created and emitted in the first place.

If you have any insights I would appreciate it.

Thanks!

databaseBuilder: (_, uid) => FirestoreDatabase(uid: uid),

No user creation

Updated:
Used the instructions and inserted the following in register_screen in order to patch the app so that user creation actually lead to a user record in the database. Alas it throws the dreaded "Error: Could not find the correct provider ..." - So what is the deal with register_screen?

FirestoreDatabase firestoreDatabase = Provider.of<FirestoreDatabase>(context);

Gradle build failed to produce

Hi Ken,

just wanna thank you, this project is amazing

I just wanna share my problem with this project

I got this error

Exception: Gradle build failed to produce an .apk file. It's likely that this file was generated under
/home/myusername/Git/create_flutter_provider_app/build, but the tool couldn't find it.

And i do solve it with creating new flutter project then copy build.grade in app folder, and paste it to your amazing template

SharedPreferences / not loading on app initialization

The issue is when I close and reopen my app, the color theme and language is not set according to my settings, it's always the default.

In lib/my_app.dart lines 40

locale: languageProviderRef.appLocale,

and 73

themeMode: themeProviderRef.isDarkModeOn

are the issue.

As these are async methods, from lib/providers/language_provider.dart and lib/providers/theme_provider.dart respectively, when the app initially runs, the information isn't there yet.

Let me know if anyone has thoughts how to fix it.

Additional Features

Hey, I'm really impressed with this starter architecture. Would be really nice if you added some additional features:

  1. Other authentication methods (google, facebook, twitter, biometrics)
  2. Responsive UI boilerplate code (sounds challenging to add responsiveness as a boilerplate code! Maybe settle with deviceWidth and deviceHeight as constants)
  3. Firebase Queries service. Some examples that came to my mind:
  • Query a collection based on one value
  • Query a collection based on multiple values, .where('docField', 'in', '[values]')
  • Query SubCollections with same name, subCollectionNames.where('docField', 'condition', 'value').groupByParent('parentCollection')
  • order a collection based on field, ascending or descending.
  1. Firebase messaging service, for sending notifications.
  2. Firebase Storage service.
  3. Firebase Analytics Service.
  4. String Validators Service. Check out this implementation
  5. Error handling service.

I know that's a lot, but you're doing a great job so far. This boilerplate structure has a high potential of easing the process for many developers.

Question: Access Firestore from Register while trying to register.

I am very new to flutter so Im still trying to wrap my head around how this project is structured and understand how data is flowing. But what I am trying to do is when a new user try's to register an account I want to first query Firestore to see if they have been invited before allowing registration to happen.

My first guess was to simply use Provider of to gain access to the FirestoreDatabase service inside the register_screen.dart file like so:

Widget _buildForm(BuildContext context) { final authProvider = Provider.of<AuthProvider>(context); final firestoreDatabase = Provider.of<FirestoreDatabase>(context, listen: false);

but got and error saying:
Could not find the correct Provider<FirestoreDatabase>

I believe this has something to do with the widget tree hierarchy and how the FirestoreDatabase is not above the register page but im not sure. Any suggestions?

Also a related question I have is FirestoreDatabase does not extend ChangeNotifier so how are we even able to use something like

Provider.of<FirestoreDatabase>(context, listen: false);

when FirestoreDatabase is not a real provider, it doesn't notify any changes? Can any regular class be pulled in with Provider.of ??

Flutter application is created using an older version of the Android embedding

Currently cannot compile caused by deprecated support of Android embedding v1. The link supplied explain quite well the changes necessary for the migration.

$ flutter build apk
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Warning
────────────────────────────────────────────────────────────
Your Flutter application is created using an older version of the Android
embedding. It is being deprecated in favor of Android embedding v2. To migrate
your project, follow the steps at:

https://github.com/flutter/flutter/wiki/Upgrading-pre-1.12-Android-projects

The detected reason was:

 .../android/app/src/main/AndroidManifest.xml uses
  `android:name="io.flutter.app.FlutterApplication"`

Build failed due to use of deprecated Android v1 embedding.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.