How to save correctly data into my model from an StreamBuilder

144

We can make use of json_serializable package available in Flutter to ease the JSON parsing and assign it to respective model class instead of assigning it manually.

You can create a methods fromJson and toJson to parse JSONObjects. However , we may need to setup some dev dependencies to make that work in our project. Please refer the documentation at Flutter

Usage will be simple like below

FirebaseFirestore.instance.collection('allUsers').snapshots().listen((event) {
    for (var element in event.docChanges) {
        final modelData = UserModel.fromJson(element.doc.data());
        // Do anything with your user. For example adding to list. 
    }
});

Model class

part 'user_model.g.dart';

@JsonSerializable()
class UserModel {
  @JsonKey(name: 'user_id')
  String userId;

  @JsonKey(name: 'name')
  String name;
  
  UserModel();

  factory UserModel.fromJson(Map<String, dynamic> json) => _$UserModelFromJson(json);

  Map<String, dynamic> toJson() => _$UserModelToJson(this);
}

Usage of json_serializable with firestore are explained in the below articles. Have it as a reference.

firestore-with-flutter-json-annotation

flutter-using-json_serializable-to-serialise

https://livebook.manning.com/book/flutter-in-action/chapter-10/v-7/54

Details are provided in bits and pieces in the example links. You may need to work it out to fit best for your requirement.

Share:
144
Omar
Author by

Omar

Updated on December 31, 2022

Comments

  • Omar
    Omar 10 months

    So I was wondering what'd the best way to save data into my model. I noticed there's not too much infotmation when it comes about StreamBuilder and Models. (both together I mean).

    This is my current model.

    class User {
      String _username, _name, _dateBorn, _gender;
    
      bool _isObserver, _notifyFriends, _recordAudio, _sendTweet;
    
      List<dynamic> _friendList;
      List<dynamic> _pendingFriends;
    
      User(
          this._username,
          this._name,
          this._dateBorn,
          this._gender,
          this._isObserver,
          this._notifyFriends,
          this._recordAudio,
          this._sendTweet,
          this._friendList,
          this._pendingFriends);
    
      String get username => _username;
      String get name => _name;
      String get dateBorn => _dateBorn;
      String get gender => _gender;
    
      bool get isObserver => _isObserver;
      bool get notifyFriends => _notifyFriends;
      bool get recordAudio => _recordAudio;
      bool get sendTweet => _sendTweet;
    
      set setNotifyFriends(bool value) => _notifyFriends = value;
      set setRecordAudio(bool value) => _recordAudio = value;
      set setSendTweet(bool value) => _sendTweet = value;
    
      List<dynamic> get friendList => _friendList;
      List<dynamic> get pendinFriends => _pendingFriends;
    }
    

    and this is my current FireStore Database.

    enter image description here

    Right now what I'm doing is this.

    StreamBuilder(
                stream:
                    FirebaseFirestore.instance.collection('Usuarios').snapshots(),
                builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
                  if (!snapshot.hasData) {
                    return Center(
                      child: CircularProgressIndicator(),
                    );
                  }
    
                  var data = snapshot.data!.docs;
                  var user;
    
                  data.forEach((element) {
                    if (element["username"] == me) {
                      user = User(
                        element["username"],
                        element["realName"],
                        element["date_birth"],
                        element["sexo"],
                        element["isObserver"],
                        element["config"]["notifyFriends"],
                        element["config"]["recordAudio"],
                        element["config"]["sendTweet"],
                        element["friends"],
                        element["pendingFriends"],
                      );
                    }
                  });
    
                  return FriendsWidget(user);
                }),
    

    But I'm pretty sure this isn't a good practice, what'd be the best practice to give the data to the model? Without losing the update-data-in-real-time feature?

    Thanks!

  • ritz
    ritz over 2 years
    in addition to the answer above, you can utilize the map() function
  • Omar
    Omar over 2 years
    Hello! thank you both for the replies, I'm sorry but I'm pretty new with flutter/dart, I'm supposed to transform the QueryDocumentSnapshot into a json object? I was wondering if you could put an example of converting the data variable into a json object and put it into the model. Thanks in advance
  • Swaminathan V
    Swaminathan V over 2 years
    Added some sample links and code snippet.
  • Omar
    Omar over 2 years
    Thanks a lot for those references, and for the code snippet!