Flutter 和 Firebase

问题描述 投票:0回答:1

我的代码有什么问题吗?该按钮预计会从用户的特定汽车集合以及全局汽车集合中删除汽车数据。

trailing: IconButton(
                                    icon: const Icon(Icons.delete, color: Colors.red),
                                    onPressed: () async {
                                      String carsId = doc.id; // Document ID of the car in the global collection
                                      try {
                                        // Check if the 'userCarId' field exists in the document before using it
                                        String userCarId = carData['userCarId'] ?? '';

                                        if (userCarId.isEmpty) {
                                          ScaffoldMessenger.of(context).showSnackBar(
                                            const SnackBar(content: Text('No userCarId found in this car document')),
                                          );
                                          return;
                                        }
                                        
                                        // Delete from the user's specific collection using userCarId
                                        await _firestore
                                            .collection('Users')
                                            .doc(currentUser!.email)
                                            .collection('Cars')
                                            .doc(userCarId) // Use the userCarId to identify the document in the user's collection
                                            .delete();

                                        // Delete from the global Cars collection
                                        await _firestore.collection('Cars').doc(carsId).delete();

                                        ScaffoldMessenger.of(context).showSnackBar(
                                          const SnackBar(content: Text('Vehicle deleted successfully')),
                                        );
                                      } catch (e) {
                                        ScaffoldMessenger.of(context).showSnackBar(
                                          const SnackBar(content: Text('Failed to delete vehicle')),
                                        );
                                      }
                                    },
                                  ),

从此程序调用 userCarId

// Adding vehicle to the user's specific collection first
      DocumentReference userCarRef = await _firestore.collection('Users').doc(userEmail).collection('Cars').add({
        'brand': brand,
        'model': model,
        'price': price,
        'transmission': transmission,
        'seats': seats,
        'mileage': mileage,
        'fuelType': fuelType,
        'registrationNumber': registrationNumber,
        'carType': carType,
        'imageURL': imageUrl, // Save the image URL
      });

      // After the vehicle is added to the user's collection, retrieve its document ID
      String userCarId = userCarRef.id;

      // Now add the vehicle to the global 'Cars' collection and set 'userCarId' to the user's car document ID
      await _firestore.collection('Cars').add({
        'brand': brand,
        'model': model,
        'price': price,
        'transmission': transmission,
        'seats': seats,
        'mileage': mileage,
        'fuelType': fuelType,
        'registrationNumber': registrationNumber,
        'carType': carType,
        'owner': userEmail,
        'imageURL': imageUrl, // Save the image URL
        'userCarId': userCarId, // Set the document ID of the user's specific car entry
      });

我尝试更改变量,等等你可以看到我的 firebase 存储,这是全球汽车集合。

enter image description here

flutter google-cloud-firestore
1个回答
0
投票

根据您的描述和代码片段,似乎出现问题是因为在尝试删除汽车时未正确检索 userCarId。发生这种情况是因为您尝试从用户的汽车文档访问 userCarId,但它仅存储在全局汽车文档中。

事情是这样的:

  • 添加汽车时,首先将其添加到用户的集合中,然后添加到全局“Cars”集合中,并将 userCarId 存储在全局文档中。
  • 但是,当您显示或操作用户集合中的汽车时,carData 不包含 userCarId,因为它未存储在用户的汽车文档中。
  • 因此,当您尝试访问 carData['userCarId'] 时,它会返回 null 或空字符串,从而导致错误。

解决方案:

要解决此问题,您应该将 globalCarId(全局“Cars”集合中汽车文档的 ID)存储在用户的汽车文档中。这样,当您从用户集合中检索汽车数据时,您可以访问删除全局汽车文档所需的 globalCarId。

以下是修改代码的方法:

  1. 添加汽车时,将globalCarId存储在用户的汽车文档中:
// Adding vehicle to the user's specific collection first
DocumentReference userCarRef = await _firestore
    .collection('Users')
    .doc(userEmail)
    .collection('Cars')
    .add({
  // car data
});

// After the vehicle is added to the user's collection, retrieve its document ID
String userCarId = userCarRef.id;

// Now add the vehicle to the global 'Cars' collection and set 'userCarId' to the user's car document ID
DocumentReference globalCarRef = await _firestore.collection('Cars').add({
  // car data
  'userCarId': userCarId, // Set the document ID of the user's specific car entry
});

String globalCarId = globalCarRef.id;

// Update the user's car document to include 'globalCarId'
await _firestore
    .collection('Users')
    .doc(userEmail)
    .collection('Cars')
    .doc(userCarId)
    .update({
  'globalCarId': globalCarId,
});
  1. 修改删除按钮代码以使用globalCarId:
trailing: IconButton(
  icon: const Icon(Icons.delete, color: Colors.red),
  onPressed: () async {
    String userCarId = doc.id; // Document ID of the car in the user's collection
    try {
      // Retrieve 'globalCarId' from 'carData'
      String globalCarId = carData['globalCarId'] ?? '';

      if (globalCarId.isEmpty) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('No globalCarId found in this car document')),
        );
        return;
      }

      // Delete from the global Cars collection using globalCarId
      await _firestore.collection('Cars').doc(globalCarId).delete();

      // Delete from the user's specific collection using userCarId
      await _firestore
          .collection('Users')
          .doc(currentUser!.email)
          .collection('Cars')
          .doc(userCarId)
          .delete();

      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Vehicle deleted successfully')),
      );
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Failed to delete vehicle')),
      );
    }
  },
),

说明:

  • 将 globalCarId 存储在用户的汽车文档中:通过使用 globalCarId 更新用户的汽车文档,您可以确保可以从用户的汽车数据中访问这两个 ID。
  • 在删除操作中使用globalCarId:删除时,您从carData中检索globalCarId并使用它从全局“Cars”集合中删除汽车。
  • 使用 doc.id 中的 userCarId:由于您在用户的汽车集合中进行操作,因此 doc.id 为您提供删除用户汽车文档所需的 userCarId。

其他提示:

  • 字段名称的一致性:确保字段名称(globalCarId、userCarId)在您的代码库中保持一致。

  • 数据完整性:考虑使用事务或批量写入来确保两个删除操作要么都成功,要么都失败,从而保持数据完整性。

  • 错误处理:通过记录错误或提供更详细的消息来改进错误处理,以帮助将来进行调试。

通过进行这些调整,您的删除按钮应该按预期工作,从用户的特定汽车集合和全局汽车集合中删除汽车数据。

© www.soinside.com 2019 - 2024. All rights reserved.