14

I want to add an object to Google Cloud Firestore in my Flutter app like this:

Firestore image

I have already made a Reply class:

class Reply {
Reply(this.replyName, this.replyText, this.replyVotes);
  final String replyName;
  final String replyText;
  final String replyVotes;

  String getName() {
    return replyName;
  }

  String getText() {
    return replyText;
  }

  String getVotes() {
    return replyVotes;
  }
}

How do I add a Reply object to cloud Firestore?

Edit: Just to clarify, I want to create a field with the data type Object which has fields inside it: Reply Object Image

2
  • Have you tried adding a Map? Commented Jul 4, 2018 at 13:18
  • 1
    How do you use a map to create a new Object inside a Firestore document? I am able to add values inside the document using a map but not create an object which has these values. Commented Jul 5, 2018 at 15:23

4 Answers 4

22

first, i highly recommend you have a single file that defines all of your schemas and/or models so there's a single point of reference for your db structure. like some file named dbSchema.dart:

import 'package:meta/meta.dart';

class Replies {

  final String title;  
  final Map coordinates;

  Replies({
    @required this.title,
    @required this.coordinates,
  });

 Map<String, dynamic> toJson() =>
  {
    'title': title,
    'coordinates': coordinates,
  };

}

and make the field that you want to be an object type Map. then, on the page you're going to insert into the db, import dbSchema.dart and create a new model:

Replies _replyObj = new Replies(
  title: _topic,
  coordinates: _coordinates,
);

this assumes you've defined your local _coordinates (or whatever) object prior to this, with something like :

_coordinates = {
 'lat': '40.0000',
 'lng': '110.000', 
};

and to then insert into Firestore, add the object's toJson method (you cannot insert/update a plain Dart model):

CollectionReference dbReplies = Firestore.instance.collection('replies');

Firestore.instance.runTransaction((Transaction tx) async {
  var _result = await dbReplies.add(_replyObj.toJson());
  ....

Update (5/31)

To convert the document read back into an object you need to add a fromJson to the class, like so:

Replies.fromJson(Map parsedJson) {
    id = parsedJson['id']; // the doc ID, helpful to have
    title = parsedJson['title'] ?? '';
    coordinates = parsedJson['coordinates'] ?? {};
}

so when you query the db:

QuerySnapshot _repliesQuery = await someCollection
        .where('title', isEqualTo: _title)
        .getDocuments();

List<DocumentSnapshot> _replyDocs = _repliesQuery.documents;

you can create an object out of each snapshot:

for (int _i = 0; _i < _replyDocs.length; _i++) {

  Replies _reply = Replies.fromJson(_replyDocs[_i].data);
  _reply.id = _replyDocs[_i].documentID;

  // do something with the new _reply object
}
Sign up to request clarification or add additional context in comments.

4 Comments

Nice answer. Adding some details on converting Firestore read document back to Dart model could be an additional help.
Great answer, useful and straightforward. +1 for @KrishnaShetty feedback. Would be great to have additional help for the reverse process. Would someone be so kind to help on that?
updated to include the mapping from a document read back into the object.
that is the case of having 2 attributes in the Replies object. What if you have more?
5

Null safe code:

Say this is your object.

class MyObject {
  final String foo;
  final int bar;

  MyObject._({required this.foo, required this.bar});

  factory MyObject.fromJson(Map<String, dynamic> data) {
    return MyObject._(
      foo: data['foo'] as String,
      bar: data['bar'] as int,
    );
  }

  Map<String, dynamic> toMap() {
    return {
      'foo': foo,
      'bar': bar,
    };
  }
}

To add this object to the cloud firestore, do:

MyObject myObject = MyObject.fromJson({'foo' : 'hi', bar: 0}); // Instance of MyObject.

var collection = FirebaseFirestore.instance.collection('collection');
collection
    .add(myObject.toMap()) // <-- Convert myObject to Map<String, dynamic>
    .then((_) => print('Added'))
    .catchError((error) => print('Add failed: $error'));

Comments

4

You can run a Firestore transaction like this:

    Firestore.instance.runTransaction((transaction) async {
          await transaction.set(Firestore.instance.collection("your_collection").document(), {
            'replyName': replyName,
            'replyText': replyText,
            'replyVotes': replyVotes,
          });
        });

3 Comments

Using this method, I am able to add values to a document. Instead what I want to do is create an Object inside a Firestore document which stores these values.
You can't not create a document (object) inside another document, first you should create a collection. Collections > documents > collections > documents ...
How do you access a sub-collection in Flutter?
1

@Laksh22 As far as I understand, you mean something like this:

Firestore.instance.runTransaction((transaction) async {
    await transaction.set(Firestore.instance.collection("your_collection").document(), {
        'reply' : {
        'replyName': replyName,
        'replyText': replyText,
        'replyVotes': replyVotes,
    }
});

just like the screenshot above.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.