Ive created a flutter app for keeping recipes.
Every recipe has a list of ingredient.
I create the recipe using a Recipe model and inside i have a list of ingredient.
By default when i save the above Recipe model to Firebase Firestore the Ingredient list is saved as an array.
I plan on expanding the concepts over time and would like to store the ingredient in a sub collection.
I am obviously able to iterate through the questions and add them as a document to their own collection, however this seems messy and likely to cause me problems in the future.
Is there a way in which i can specify that child models are created as a sub collection rather than an array?
Below is what im using currently to write the data
class FirestoreService {
FirestoreServiceNew._();
static final instance = FirestoreServiceNew._();
Future<void> setData({
@required String path,
@required Map<String, dynamic> data,
bool mergeBool = false,
}) async {
try {
final reference = FirebaseFirestore.instance.doc(path);
print('$path: $data');
await reference.set(data);
} catch (e) {
print('error: $e');
}
}
Future<void> bulkSet({
@required String path,
@required List<Map<String, dynamic>> datas,
bool merge = false,
}) async {
final reference = FirebaseFirestore.instance.doc(path);
final batchSet = FirebaseFirestore.instance.batch();
print('$path: $datas');
}
Future<void> deleteData({@required String path}) async {
final reference = FirebaseFirestore.instance.doc(path);
print('delete: $path');
await reference.delete();
}
Stream<List<T>> collectionStream<T>({
@required String path,
@required T builder(Map<String, dynamic> data, String documentID),
Query queryBuilder(Query query),
int sort(T lhs, T rhs),
}) {
Query query = FirebaseFirestore.instance.collection(path);
if (queryBuilder != null) {
query = queryBuilder(query);
}
final Stream<QuerySnapshot> snapshots = query.snapshots();
return snapshots.map((snapshot) {
final result = snapshot.docs
.map((snapshot) => builder(snapshot.data(), snapshot.id))
.where((value) => value != null)
.toList();
if (sort != null) {
result.sort(sort);
}
return result;
});
}
Stream<List<T>> requestStream<T>({
@required String path,
@required T builder(Map<String, dynamic> data, String documentID),
Query queryBuilder(Query query),
int sort(T lhs, T rhs),
}) {
Query query = FirebaseFirestore.instance.collection(path);
if (queryBuilder != null) {
query = queryBuilder(query);
}
final Stream<QuerySnapshot> snapshots = query.snapshots();
return snapshots.map((snapshot) {
final result = snapshot.docs
.map((snapshot) => builder(snapshot.data(), snapshot.id))
.where((value) => value != null)
.toList();
if (sort != null) {
result.sort(sort);
}
return result;
});
}
Stream<T> documentStream<T>({
@required String path,
@required T builder(Map<String, dynamic> data, String documentID),
}) {
final DocumentReference reference = FirebaseFirestore.instance.doc(path);
final Stream<DocumentSnapshot> snapshots = reference.snapshots();
return snapshots.map((snapshot) => builder(snapshot.data(), snapshot.id));
}
}
and my model
class Recipe {
String id;
List<Ingredient> ingredients;
String title;
String description;
Timestamp createdOn;
Recipe(
{this.id = '',
this.ingredients,
this.title,
this.description,
this.createdOn});
Recipe.fromData(Map<String, dynamic> json, String docid) {
id = docid ?? '';
title = json['title'];
description = json['description'];
createdOn = json['createdOn'];
if (json['questions'] != null) {
ingredients= new List<Ingredients>();
json['ingredients'].forEach((v) {
questions.add(new Ingredients.fromData(v, null));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['description'] = this.description;
data['title'] = this.title;
data['createdOn'] = this.createdOn;
if (this.ingredients != null) {
data['ingredients'] = this.ingredients.map((v) => v.toJson()).toList();
}
return data;
}
}
You can build a path to documents nested in subcollections by alternating calls to collection() and doc() , which return CollectionReference and DocumentReference objects respectively.
FirebaseFirestore.instance
.collection("top-level-collection")
.doc("document-id-1")
.collection("nested-subcollection")
.doc("document-id-2")
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.