top of page

[Flutter]Manage state by linking Firestore and Redux


Overview


In a smartphone app that handles user data, I would like to write about how to link the state management while using the app with the external storage for data storage.

Specifically, redux is used for state management within the app, and cloud firestore is used for data storage (this is just an example, and there are other options).



Method


Overview


  1. Data is stored in the firestore for each user.

  2. When user A launches the smartphone app, sign in using a google account

  3. After successful authentication of google account, get user A's data from firestore and store it in redux stroe

  4. If user change the data, change the data on the firestore with the redux middleware


Firestore configuration


Create a "users" collection in the firestore and stores each user's data as a document. The document id is a google account.



Login and authemtification


When the app starts, the login page prompts the user for a google account. Authenticate using firebase auth, and if authentication is successful, get the user data of that gmail address from firestore.

For example, the process to get the user's data from the firestore from the User instance of firebase auth is as follows.


Future<AppState> get_data(User user)async{
    FirebaseFirestore db;
    DocumentReference docRef;
    CollectionReference colRef;
    
    //initialize firestore instance
    db=FirebaseFirestore.instance;
    
    //Get a reference to the user's data with a gmail address
    colRef=await db.collection('users');    
    docRef=await colRef.doc(user.email);

    var snapshot=await docRef.get();
    if (!snapshot.exists){
        //If the user data does not exist, add a new one
      await colRef.doc(user.email).set({'name': user.displayName});
      docRef=await colRef.doc(user.email);
    }
    
    //Get data from reference and store in map
    var col_items
        =await docRef.collection('items').get();

    Map<int, String>items={};
    for(var snapshot in col_items.docs){
      int id=int.parse(snapshot.id);
      items[id]=snapshot.data()['item'];
    }
    
    return AppState(items: items);
}

As an example, I assumed the case of int type id and String type data (item) map.

class AppState{
  Map<int, String> items;
  
  AppState({this.items});
  
  AppState.initState(){
    items={};
  }
}

Store in store


Initialize the store using the data obtained above.

There is also a method of initializing with empty data and then retrieving the data with middleware (or maybe that is better).


AppState state;
try {
  state = await fireStore.initDataSets(user);
}
catch(Exception){
  state=AppState.initState();
}

Store<AppState> store=Store<AppState>(
  appStateReducer,
  initialState: state,
  middleware: [AppStateMiddleWare]
);

Reflect data changes in firestore


Pass a reference to the firestore's user's document to action, and midlleware will use that reference to write to the firestore. In the above get_data, the reference is stored in a local variable, but it may be convenient to make it a class member.


middleware

void AppStateMiddleWare(Store<AppState> store, dynamic action, 
                        NextDispatcher next) async {                             
    next(action);
     
    if (action is AddItemAction){

        var docRef=action.docRef;
        int id=action.id;
        await docRef.collection('items')
              .doc(id.toString()).set({'item': action.item});
    }
}

action

class AddItemAction{
  final String item;
  final int id;
  final DocumentReference docRef;

  AddItemAction({this.item, this.id, this.docRef});
}


Lastly


I think there are quite a lot of uses like this, but I don't see any methodology at all, so I wrote it. It is used only for personal development, so please use it as a reference only.

Recent Posts

See All

[Flutter/Dart] Format string with TextField

What want to do I want to create an input form using TextField. For example, if the input content is a monetary amount, I would like to display it in 3-digit delimiters with a ¥ prefix. Rather than ha

Comments


Let's do our best with our partner:​ ChatReminder

iphone6.5p2.png

It is an application that achieves goals in a chat format with partners.

google-play-badge.png
Download_on_the_App_Store_Badge_JP_RGB_blk_100317.png

Let's do our best with our partner:​ ChatReminder

納品:iPhone6.5①.png

It is an application that achieves goals in a chat format with partners.

google-play-badge.png
Download_on_the_App_Store_Badge_JP_RGB_blk_100317.png

Theme diary: Decide the theme and record for each genre

It is a diary application that allows you to post and record with themes and sub-themes for each genre.

google-play-badge.png
Download_on_the_App_Store_Badge_JP_RGB_blk_100317.png
bottom of page