【问题标题】:How to fix a method/functionality in Flutter being executed so many times without loop?如何在没有循环的情况下修复 Flutter 中多次执行的方法/功能?
【发布时间】:2022-11-11 22:44:37
【问题描述】:

我正在开发一个 Flutter 项目,它是一个三轮车预订系统,也使用 Firebase 中的实时数据库。如果驾驶员已接受乘客的乘车状态,将执行音频或通知声音,然后将显示模态弹出/对话框。

经尝试,只要接受乘客的乘车状态,这两个功能就会无限次多次执行。我如何只实现一次,它背后的原因是什么,因为我没有为此使用任何循环?

以下是此方法的更新代码:

   saveRideRequestInformation() //Ride Request Code
  {
    //1. save the Ride Request Information

    referenceRideRequest = FirebaseDatabase.instance.ref().child("All Ride Requests").push(); // Creates unique ID
    String? rideKey = referenceRideRequest!.key.toString();

    var originLocation = Provider.of<AppInfo>(context, listen: false).userPickUpLocation;
    var destinationLocation = Provider.of<AppInfo>(context, listen: false).userDropOffLocation;

    Map originLocationMap =
    {
      //key:value
      "latitude": originLocation!.locationLatitude.toString(),
      "longitude": originLocation!.locationLongitude.toString(),
    };

    Map destinationLocationMap =
    {
      //key:value
      "latitude": destinationLocation!.locationLatitude.toString(),
      "longitude": destinationLocation!.locationLongitude.toString(),
    };

    Map userInformationMap =
    {
      "origin": originLocationMap,
      "destination": destinationLocationMap,
      "time": DateTime.now().toString(),
      "username": userModelCurrentInfo!.username!,
      "email": userModelCurrentInfo!.email!,
      "id": userModelCurrentInfo!.id!,
      "requestId": rideKey,
      "originAddress": originLocation.locationName,
      "destinationAddress": destinationLocation.locationName,
      "driverId": "waiting",
      "notified" : "false",
    };

    referenceRideRequest!.set(userInformationMap);

    tripRideRequestInfoStreamSubscription = referenceRideRequest!.onValue.listen((eventSnap) async // getting updates in real time
    {
      if(eventSnap.snapshot.value == null)
        {
          return;
        }

      if ((eventSnap.snapshot.value as Map)["driverPlateNum"] != null) //!! GAWING CAR DETAILS/ PLATE NUMBER
      {
        setState(() {
          driverTricDetails = (eventSnap.snapshot.value as Map)["driverPlateNum"].toString();
        });
      }

      if ((eventSnap.snapshot.value as Map)["driverPhone"] != null) //!! GET PHONE NUMBER
          {
        setState(() {
          driverPhone = (eventSnap.snapshot.value as Map)["driverPhone"].toString();
        });
      }

      if ((eventSnap.snapshot.value as Map)["notified"] != null) //!! GET PHONE NUMBER
          {
        setState(() {
          notified = (eventSnap.snapshot.value as Map)["notified"].toString();
        });
      }

      if ((eventSnap.snapshot.value as Map)["driverName"] != null) //!! GET FNAME
          {
        setState(() {
          driverName = (eventSnap.snapshot.value as Map)["driverName"].toString();
        });
      }

      if((eventSnap.snapshot.value as Map)["status"] != null)
      {
        setState(() {
          userRideRequestStatus = (eventSnap.snapshot.value as Map)["status"].toString();
        });
      }

      if((eventSnap.snapshot.value as Map)["driverLocation"] != null)
      {
        double driverCurrentPositionLat = double.parse((eventSnap.snapshot.value as Map)["driverLocation"]["latitude"].toString());
        double driverCurrentPositionLng = double.parse((eventSnap.snapshot.value as Map)["driverLocation"]["longitude"].toString());

        LatLng driverCurrentPositionLatLng = LatLng(driverCurrentPositionLat, driverCurrentPositionLng);

        if(userRideRequestStatus != null)
        {
          isVisible= !isVisible;
          showUIForAssignedDriverInfo();

          //when status = accepted
          if(userRideRequestStatus == "accepted" && notified == "false") {
            FirebaseDatabase.instance.ref()
                .child("All Ride Requests")
                .child(rideKey)
                .child("notified")
                .set("true");

            passengerIsOfflineNow();
            assignedDriverModal();

            updateArrivalTimeToUserPickupLocation(driverCurrentPositionLatLng);
          }

          //when status = arrived
          if(userRideRequestStatus == "arrived")
          {
            setState(() {
              driverRideStatus = "Your driver has arrived.";
            });
          }

          //when status = onTrip
          if(userRideRequestStatus == "onTrip")
          {
            updateReachingTimeToUserDropOffLocation(driverCurrentPositionLatLng);
          }

          //when status = ended
          if(userRideRequestStatus == "ended")
          {
            if((eventSnap.snapshot.value as Map)["fareAmount"] != null)
            {
              double fareAmount = double.parse((eventSnap.snapshot.value as Map)["fareAmount"].toString());

              var response = await showDialog(
                context: context,
                barrierDismissible: false,
                builder: (BuildContext c) => PayFareAmountDialog(
                  fareAmount: fareAmount,
                ),
              );

              if(response == "cashPayed")
              {
                //user can rate the driver
                if((eventSnap.snapshot.value as Map)["driverId"] != null)
                {
                  String assignedDriverId = (eventSnap.snapshot.value as Map)["driverId"].toString();

                  Navigator.push(context, MaterialPageRoute(builder: (c)=> RateDriverScreen(
                    assignedDriverId: assignedDriverId,
                  )));

                  referenceRideRequest!.onDisconnect();
                  tripRideRequestInfoStreamSubscription!.cancel();
                }
              }
            }
          }
      }
    }
    });

    onlineNearbyAvailableDriversList = GeoFireAssistant.activeNearbyAvailableDriversList;
    //searchNearestOnlineDrivers();
  }

【问题讨论】:

    标签: flutter firebase dart firebase-realtime-database


    【解决方案1】:

    这是因为驱动程序位置更新时运行的快照侦听器。随着驱动程序位置的更新,它会遍历 if 语句中的所有内容。这具体:

    if((eventSnap.snapshot.value as Map)["driverLocation"] != null)
          {
            double driverCurrentPositionLat = double.parse((eventSnap.snapshot.value as Map)["driverLocation"]["latitude"].toString());
            double driverCurrentPositionLng = double.parse((eventSnap.snapshot.value as Map)["driverLocation"]["longitude"].toString());
    
            LatLng driverCurrentPositionLatLng = LatLng(driverCurrentPositionLat, driverCurrentPositionLng);
    
            if(userRideRequestStatus != null)
            {
              isVisible= !isVisible;
              showUIForAssignedDriverInfo();
    
              //when status = accepted. !! this is my concern !!
              if(userRideRequestStatus == "accepted")
    ...
    

    您可以考虑做的是在eventSnap.snapshot.value 中添加一个标志来说明通知的内容。然后在运行if(userRideRequestStatus == "accepted") 语句后,将notified 值翻转为true。然后,这会将您接受的 if 语句从 if(userRideRequestStatus == "accepted") 更改为 if(userRideRequestStatus == "accepted" &amp;&amp; !driverNotified)

    【讨论】:

    • 添加标志是什么意思?
    • 你能举个例子吗,我很困惑。 :(我只需要在接受状态时显示对话框,我想不出任何其他条件......
    • 我是说您可以向您的 RTDB 添加一个值,将其存储为 false,直到您向驱动程序发送通知,然后将该标志翻转为 true,以便您的代码知道您已经通知了驱动程序。如果值不断运行if((eventSnap.snapshot.value as Map)["driverLocation"] != null),然后运行if(userRideRequestStatus == "accepted"),因为它包含在其中。
    • 我现在明白了,但你能举一个关于如何实现它的代码示例吗?
    • 嘿,我试过做你的评论,它以某种方式解决了我的问题,但它仍然重复了 5 次,为什么?请帮忙 :(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-11
    • 2015-02-12
    • 2023-03-03
    • 1970-01-01
    • 2016-07-13
    相关资源
    最近更新 更多