【问题标题】:How to get the ID of the document in a subcollection?如何获取子集合中文档的ID?
【发布时间】:2021-09-28 09:01:09
【问题描述】:

我想使用“食物”子集合中的数据进行 CRUD,但我不明白如何获取子集合的 ID

restaurantCollection
        .doc(uid)
        .collection('food')
        .doc(docId)
        .update(data);

我知道这是为了更新 food 子集合中的字段,但我实际上如何获得 docId

final CollectionReference restaurantCollection =
      FirebaseFirestore.instance.collection('restaurant');

Future addFoodData(String description, String name, double oriPrice,
      double salePrice, int pax) async {
    return await restaurantCollection.doc(uid).collection('food').doc().set({
      'ruid': uid, //i stored the parent's ID in the child
      'name': name,
      'description': description,
      'oriPrice': oriPrice,
      'salePrice': salePrice,
      'pax': pax,
    });
  }

 List<Food> _foodListFromSS(QuerySnapshot snapshot) {
    return snapshot.docs.map((doc) {
      return Food(
        name: doc.data()['name'] ?? '',
        description: doc.data()['description'] ?? '',
        oriPrice: doc.data()['oriPrice'] ?? 0.0,
        salePrice: doc.data()['salePrice'] ?? 0.0,
        pax: doc.data()['pax'] ?? 0,
      );
    }).toList();
  }

Stream<List<Food>> get food {
    return restaurantCollection
        .doc(uid)
        .collection('food')
        .snapshots()
        .map(_foodListFromSS);
  }

^database.dart 这就是我创建数据的方式。

class Menu extends StatefulWidget {
  @override
  _MenuState createState() => _MenuState();
}

class _MenuState extends State<Menu> {
  bool loading = false;

  @override
  Widget build(BuildContext context) {
    final user = Provider.of<Users>(context);
    return loading
        ? Loading()
        : StreamProvider<List<Food>>.value(
            initialData: [],
            value: DatabaseService(uid: user.uid).food,
            child: Scaffold(
              appBar: ElrAppBar('Menu', false),
              drawer: ElrDrawer(),
              floatingActionButton: FloatingActionButton(
                onPressed: () {
                  print('ADD MENU Pressed');
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => MenuAdd(),
                    ),
                  );
                },
                child: const Icon(Icons.add),
              ),
              body: Container(
                padding: EdgeInsets.symmetric(horizontal: 10),
                width: double.infinity,
                color: Colors.grey,
                child: FoodList(),
              ),
            ),
          );
  }
}

^menu.dart

class FoodList extends StatefulWidget {
  @override
  _FoodListState createState() => _FoodListState();
}

class _FoodListState extends State<FoodList> {
  bool loading = false;

  @override
  Widget build(BuildContext context) {
    final food = Provider.of<List<Food>>(context);
    return loading
        ? Loading()
        : ListView.builder(
            itemCount: food.length,
            itemBuilder: (context, index) {
              return GestureDetector(
                onTap: () => Navigator.push(context,
                    MaterialPageRoute(builder: (context) => MenuUpdate())),
                child: Card(
                    margin: EdgeInsets.fromLTRB(0, 10, 0, 0),
                    child: FoodTile(food: food[index])),
              );
            },
          );
  }
}

^food_list.dart

class FoodTile extends StatelessWidget {
  final Food food;
  FoodTile({this.food});

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Container(
        margin: EdgeInsets.all(5),
        child: Row(
          children: [
            Container(
              color: colorsConst[900],
              width: 100,
              height: 100,
            ),
            SizedBox(width: 10),
            Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  food.name.inCaps,
                  style: TextStyle(
                    fontWeight: FontWeight.bold,
                    fontSize: 20,
                  ),
                ),                
                SizedBox(height: 4),
                Container(
                  width: 260,
                  child: Text(
                    food.description.inCaps,
                    style: TextStyle(fontSize: 15, fontStyle: FontStyle.italic),
                  ),
                ),
                SizedBox(height: 4),
                foodInfoCard('Original price: ',
                    'RM ${food.oriPrice.toStringAsFixed(2).toString()}'),
                SizedBox(height: 4),
                foodInfoCard('Selling price: ',
                    'RM ${food.salePrice.toStringAsFixed(2).toString()}'),
                SizedBox(height: 4),
                foodInfoCard('Available pax: ', food.pax.toString()),
              ],
            ),
          ],
        ),
      ),
    );
  }

^food_tile.dart

这是我从子集合中获取食物列表的方式。 当我点击 food_list.dart 中的卡片时,我不知道如何从子集合中只返回一个特定数据。

我遇到了一个死胡同,我很迷茫。我希望有一些人会很乐意帮助我。 如果需要,请询问更多信息。提前谢谢你!

【问题讨论】:

  • 您应该已经将该 ID 存储在您的应用程序中。您已经拥有父类别的 uid。食物是恒定的。在更新之前如何获取原始数据?您无法更新没有 ID 的文档。如果您要在 food 子集合中创建新文档,请使用 .set
  • @HuthaifaMuayyad 这听起来几乎是一个答案。您想添加它以便 Marini 和其他未来的开发者可以利用它吗?
  • @HuthaifaMuayyad 我添加了用于创建和阅读 food 子集合中的文档的编码。我真的不知道如何将一份文件的数据返回给我的 CRUD。 :'(
  • @AlexMamo 如果您不介意,您也可以分享。呵呵

标签: android firebase flutter google-cloud-firestore


【解决方案1】:

您应该已经将 id 存储在您的应用程序中。您已经拥有父类别的uid。而food 是不变的。在更新之前如何获取原始数据?您无法更新没有其 ID 的文档。如果您要在 food 子集合中创建新文档,请使用 .set()

当你执行这个操作时:

Future addFoodData(String description, String name, double oriPrice,
      double salePrice, int pax) async {
    return await restaurantCollection.doc(uid).collection('food').doc().set({
      'ruid': uid, 
      'id': generateRandowId,//Create an ID and store it here.
      'name': name,
      'description': description,
      'oriPrice': oriPrice,
      'salePrice': salePrice,
      'pax': pax,
    });
  }

将来当您获取这些文档时,它会有一个“ID”字段,您可以使用它来更新它。因为您在子集合中有文档的父 ruidfood 以及现在的 id。 我还建议您从这些文档中创建对象\模型。在处理['keys'] 时,这将使他们更容易使用,并且更不容易出错。

【讨论】:

  • 好吧,我想我明白你的意思了。所以,我声明了一个var newFoodDoc = restaurantCollection.doc(uid).collection('food').doc();,然后我返回了return await newFoodDoc.set({'fid': newFoodDoc.id, ... });,它创造了奇迹!非常感谢您的澄清!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-24
  • 2022-07-08
  • 1970-01-01
  • 2021-02-16
  • 2022-07-11
  • 1970-01-01
相关资源
最近更新 更多