dart 锁定firebase firestore收集和写入数据+ flutter

jgzswidk  于 9个月前  发布在  Flutter
关注(0)|答案(1)|浏览(131)

我有一个这样的场景
当用户尝试更新集合中的字段“sample”时:

  • 我有一个检查,看看该字段是否为空。
  • 当该字段为空时,更新该字段并显示更新成功的吐司消息
  • 当该字段不为空时,仅显示更新失败的吐司消息

我面临的问题是
当两个用户同时更新字段时(仅毫秒差异):

  • 用户1收到成功消息
  • 用户2也会收到成功消息
  • 但是只有用户2的数据被更新

我认为这个问题是因为时差很小。可能是:

  • 当用户1检查该字段时-其为空
  • 当用户2检查该字段时-它也是空的
  • 用户1更新值
  • 用户2还更新覆盖用户1的值的值

当用户1检查字段并进行更新时,是否有方法锁定字段的更新,以便用户2无法更新同一字段中的值
在这里我添加了示例代码:

if (ownerId.isEmpty && equipmentId.isEmpty) {
         dm
            .assignBooking(
                bid: bid,
                status: 'approved',
                ownerId: uid,
                equipmentid: eid!,
                model: model,
                bookingType: notificationBookingType)
            .then((value) {
            if (value == true) {
            
              Fluttertoast.showToast(
                  msg: AppLocalizations.of(context)!
                      .bookingsuccessfullyApproved,
                  timeInSecForIosWeb: 5);
            } else {
              Fluttertoast.showToast(
                  msg: AppLocalizations.of(context)!
                      .bookingAcceptedBysomeoneElse,
                  timeInSecForIosWeb: 5);
            }

Future<bool> assignBooking({
required String bid,
required String status,
required String ownerId,
required String equipmentid,
required String model,
required String bookingType,
}) async {
// Fetch the existing booking data
var bookingData = await allBookings.doc(bid).get();

// Check if assigned_equipment_owner_id is empty
if (bookingData['assigned_equipment_owner_id'] == null ||
    bookingData['assigned_equipment_owner_id'].isEmpty) {
  // Update only if assigned_equipment_owner_id is empty
  await allBookings.doc(bid).update({
    "status": status,
    'assigned_equipment_owner_id': ownerId,
    'equipment_id': equipmentid,
    'model': model,
    'booking_type': bookingType,
  });
  return true;
} else {
  return false;
}
}

字符串
在更新和显示吐司消息之前,我正在检查所有者ID和设备ID是否在两个地方为空。但我仍然无法处理这个问题

lstz6jyr

lstz6jyr1#

您面临的问题与竞争条件有关,其中两个用户同时检查条件(assigned_equipment_owner_id为空),并且他们都发现它为空。因此,两个用户都继续更新数据,导致都收到成功消息,但实际上只有一个更新反映在数据库中。
要处理这种情况,您需要实现一种机制来确保更新操作中的原子性,这样每次只有一个用户可以成功地更新数据。
一种方法是使用事务来确保检查和更新操作被视为单个原子单元。这有助于避免多个用户可能试图同时更新数据的竞争条件。

Future<bool> assignBooking({
  required String bid,
  required String status,
  required String ownerId,
  required String equipmentid,
  required String model,
  required String bookingType,
}) async {
  try {

    await FirebaseFirestore.instance.runTransaction((transaction) async {
      var bookingData = await allBookings.doc(bid).get();

      
      if (bookingData['assigned_equipment_owner_id'] == null ||
          bookingData['assigned_equipment_owner_id'].isEmpty) {
        transaction.update(allBookings.doc(bid), {
          "status": status,
          'assigned_equipment_owner_id': ownerId,
          'equipment_id': equipmentid,
          'model': model,
          'booking_type': bookingType,
        });
      } else {
        
        throw 'Equipment is already assigned to another owner.';
      }
    });

   
    return true;
  } catch (e) {
    return false;
  }
}

字符串

相关问题