问题描述
我正在尝试在 Firebase 中获取一个集合并将其转换为字符串列表并使用它创建一些条件。我正在为商店创建一个应用程序,我的目的是应用一种方法,当我按下产品中的按钮时,为每个用户创建收藏夹列表。要在 firebase 中添加最喜欢的产品,我正在使用它,并且可以正常工作:
_saveFavorite(Product product) async {
await _loadCurrentUser(); //So I get the user ID
Firestore db = Firestore.instance;
db.collection("my_favorites")
.document(_userID)
.collection("products")
.document(product.id)
.setData(product.toMap());
}
要删除最喜欢的产品,我正在使用它:
_removeFavorite(String productID) async {
await _loadCurrentUser();
Firestore db = Firestore.instance;
db.collection("my_favorites")
.document(_userID)
.collection("products")
.document(product.id)
.delete();
}
所以,这是这样的:收藏(“my_favorites”)> 文档(用户ID)> 收藏(“产品”)> 文档(产品ID)> 产品保存为收藏。
我正在尝试获取保存在 Collection("products") 中的所有 productsID 以创建凸起按钮的条件,但我不知道该怎么做。我想按下这个按钮并设置如下条件: listofIDProducts.contains(product.id) ? _removeFavorite : _saveFavorite;
感谢您的关注,如果您能帮助我,我非常感谢!
解决方法
您可以将这样的列表存储在 /my_favorites/USER_ID
文档中,作为当前收藏的产品 ID 的数组。您可以使用 Cloud Functions 维护此列表,因为在 /my_favorites/USER_ID/products
集合中添加和删除每个产品,但可以说仅使用 batched write 和 array field transforms、{ {3}} 和 arrayUnion()
。
_saveFavorite(Product product) async {
await _loadCurrentUser();
Firestore db = Firestore.instance;
WriteBatch batch = db.batch();
// queue adding the product's ID to the products array
batch.update(
db.collection("my_favorites")
.document(_userID),{
products: FieldValue.arrayUnion([product.id])
}
);
// queue uploading a copy of the product's data to this user's favorites
batch.set(
db.collection("my_favorites")
.document(_userID)
.collection("products")
.document(product.id),product.toMap()
);
return batch.commit();
}
_removeFavorite(String productID) async {
await _loadCurrentUser();
Firestore db = Firestore.instance;
WriteBatch batch = db.batch();
// queue removing product.id from the products array
batch.update(
db.collection("my_favorites")
.document(_userID),{
products: FieldValue.arrayRemove([product.id])
}
);
// queue deleting the copy of /products/PRODUCT_ID in this user's favorites
batch.delete(
db.collection("my_favorites")
.document(_userID),.collection("products")
.document(product.id)
);
return batch.commit();
}
要获取产品 ID 列表,您可以使用类似于以下内容的内容:
_getFavoriteProductIDs() async {
await _loadCurrentUser();
Firestore db = Firestore.instance;
return db.collection("my_favorites")
.document(_userID)
.get()
.then((querySnapshot) {
return querySnapshot.exists ? querySnapshot.get("products") : []
});
}
您甚至可以将其转换为使用列表:
_saveFavorite(List<Product> products) async {
if (products.length == 0) {
return; // no action needed
}
await _loadCurrentUser();
Firestore db = Firestore.instance;
WriteBatch batch = db.batch();
// queue adding each product's ID to the products array
batch.update(
db.collection("my_favorites")
.document(_userID),{
products: FieldValue.arrayUnion(
products.map((product) => product.id).toList()
)
}
);
// queue uploading a copy of each product to this user's favorites
for (var product in products) {
batch.set(
db.collection("my_favorites")
.document(_userID)
.collection("products")
.document(product.id),product.toMap()
);
}
return batch.commit();
}
_removeFavorite(List<String> productIDs) async {
if (productIDs.length == 0) {
return; // no action needed
}
await _loadCurrentUser();
Firestore db = Firestore.instance;
WriteBatch batch = db.batch();
// queue removing each product ID from the products array
batch.update(
db.collection("my_favorites")
.document(_userID),{
products: FieldValue.arrayRemove(productIDs)
}
);
// queue deleting the copy of each product in this user's favorites
for (var product in products) {
batch.delete(
db.collection("my_favorites")
.document(_userID)
.collection("products")
.document(product.id)
);
}
return batch.commit();
}
附加说明:在您当前的实施中,收藏的产品从 /products/PRODUCT_ID
复制到 /my_favorites/USER_ID/products/PRODUCT_ID
。请记住,使用这种结构,如果 /products/PRODUCT_ID
被更新,您将必须更新该产品的每个副本。我建议将 products
重命名为 favorited-products
,以便您可以使用 arrayRemove()
和 Cloud Function 实现此目的(有关详细信息,请参阅 Collection Group Query)。