如何将 Firebase 中的集合转换为字符串列表并使用它创建一些条件

问题描述

我正在尝试在 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 writearray 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)。