Reputation: 83
I'm new to firestore and I'm still trying to wrap my head around it. I made an app in flutter/dart only to realize that the way I was modeling my data:
class1.[class1_index].class2.[class2_index].class3.[class3_index] etc...
This is not possible in firestore.
I have been trying to figure out alternatives, and I would like to start by having only 1 collection, and nesting all of the data inside of the documents in that collection, as opposed to creating subcollections.
Note : I am using json_serializable, annotation and build_runner dependencies and have annotated the model classes accordingly
So far, I have tried nesting maps of objects (as opposed to lists of objects, which isnt supported) as an alternatives and I'm running into some problems with this approach as well.
The issue I'm having here is when I try to create a second level object class1[key].createClass2Object(), and then doc.set(class1[key].toJson()), I get the error 'invalid argument type, instance of Block':
void createBlock(String block_name, int clientIndex) async {
blocks[block_name] = Block(name: block_name);
blckLst.add(blocks.keys.last);
await FirebaseFirestore.instance //error here
.collection('users')
.doc(AuthService().currentUser?.uid)
.collection('clients')
.doc(docID)
.set(clients[currentClient].toJson());
}
Since it seems that firestore didn't like 'Block' (instance of Class2/second level) when setting the document to Client.toJson, I tried converting 'Block' toJson upon instantiation:
void createBlock(String block_name, int clientIndex) async {
blocks[block_name] = Block(name: block_name).toJson();
blckLst.add(blocks.keys.last);
await FirebaseFirestore.instance
.collection('users')
.doc(AuthService().currentUser?.uid)
.collection('clients')
.doc(docID)
.set(clients[currentClient].toJson());
}
Now this got my map of second level objects into firestore, however since 'Block's are being instantiated as Json, I am unable to access their properties and methods (3rd level objects, name property etc) and am getting 'NoSuchMethod no instance getter' here:
return ExpansionTile(
collapsedBackgroundColor: background_color1,
backgroundColor: background_color1,
title: Center(
child: Text(
clients[currentClient]
.blocks[currentBlock]
.name, //error here
style: TextStyle(color: fontcolor),
)),
children: [
clients[currentClient]
.blocks[currentBlock]
.mesocycles //error here
.length >
0
? ListView.builder(
shrinkWrap: true,
itemCount: clients[currentClient]
.blocks[currentBlock]
.mesocycles //error here
.length,
itemBuilder: (context, index2) {
return Container(
I have been stuck at this stage of trying to get my app to work with firestore for a week now, meanwhile it only took my a few weeks to make the actual app functionality, so I am more than ready to move on and I'm frustrated to be so close to having a working prototype, but I need some guidance.
If you have any advice or solutions to my data modeling problems, please share them in the comments or as an answer.
Upvotes: 0
Views: 170
Reputation: 83
Okay the errors I was getting in Attempt #2 case above, were from using:
blocks[currentBlock].mesocycles.length
instead of:
blocks[currentBlock]['mesocycles'].length
since each 'Block' is being converted toJson when instantiated, I need to access it as such.
Still at a bit of a loss on how I should be structuring this to make it as simple as possible to use with Firestore.
I'm considering just making the map keys strings that are converted from the builder widgets indexes, so I can access the nested data through composite indexes like I originally intended with my initial 'nested arrays' approach.
Upvotes: 1