Home > database >  Firebase :: Allow read write access if the uid of another node (user/driver node) is verified
Firebase :: Allow read write access if the uid of another node (user/driver node) is verified

Time:01-10

I have 2 nodes in my realtime database (activeDrivers and ALL Ride Request) which are used by both users and drivers and therefore I want them to be accessible when the uid of one or the other is present. But it doesn't work.

The activeDrivers table assigns ids equal to those of the driver executing the query while the All Ride Request table assigns an ever-changing randomly generated value as id

{
  "rules": {
    "drivers": {
      "$uid": {
        ".read": "auth !== null && auth.uid === $uid",
        ".write": "auth !== null && auth.uid === $uid",
      }

    },
    "activeDrivers": {
      ".read": "root.child('users/uid').exists() || root.child('drivers/uid').exists()",
      ".write": "root.child('users/uid').exists() || root.child('drivers/uid').exists()",
      ".indexOn": ["g"]
    },
    "users": {
      "$uid": {
        ".read": "auth !== null && auth.uid === $uid",
        ".write": "auth !== null && auth.uid === $uid",
      }
    },
    "ALL Ride Requests": {
      ".read": "root.child('users/uid').exists() || root.child('drivers/uid').exists()",
      ".write": "root.child('users/uid').exists() || root.child('drivers/uid').exists()",
    }
  }
}

This is JSON of database

{
  "ALL Ride Requests": {
    "-NJlIOrp49pNBSuuEawT": {
      "destination": {
        "latitude": "41.929612",
        "longitude": "12.4858561"
      },
      "destinationAddress": "Duke's",
      "driverId": "waiting",
      "origin": {
        "latitude": "41.919225",
        "longitude": "12.5266267"
      },
      "originAddress": "Circonvallazione Nomentana, 270, 00162 Roma RM, Italy",
      "time": "2022-12-20 21:50:48.437521",
      "userName": "Peter Parker",
      "userPhone": "090012321354"
    },
  },
  "activeDrivers": {
    "G3OJ79KiLeMmxqoUpJ1NggIKbiF2": {
      ".priority": "sr2yt23wk8",
      "g": "sr2yt23rk8",
      "l": [
        41.926275,
        12.5376567
      ]
    },
  },
  "drivers": {
    "G3OJ79KiLeMmxqoUpJ1NggIKbiF2": {
      "earnings": "0.0",
      "email": "[email protected]",
      "id": "G3OJ79KiLeMmxqoUpJ1NggIKbiF2",
      "name": "Simone Demichele Test",
      "newRideStatus": "idle",
      "password": "testpassword",
      "phone": "3452362585",
      "token": "fFIwv1IHRv2ylXyW-qRVGQ:APA91bH7IfcNBBi7Y53wRjQKN12-nBUgFHHpf7F0LeWCstG_MIqt-mkobRN6nvUZxqbMnMlXU2yMHdE-efYykUdtcXl-91wW5rGyQcpMl6Dij6bxC8snQRkAMGBhQUmyqYW6sBhY6Ul3"
    },
  },
  "users": {
    "yHc7xseCT0QePnpolGHZvdr8ARV2": {
      "email": "[email protected]",
      "id": "yHc7xseCT0QePnpolGHZvdr8ARV2",
      "name": "Peter Parker",
      "phone": "090012321354"
    }
  }
}

Code Example for ALL Ride Request instance

getDriversLocationUpdatesAtRealTime()
  {
    LatLng oldLatLng = LatLng(0, 0);

    streamSubscriptionDriverLivePosition = Geolocator.getPositionStream()
        .listen((Position position)
    {
      driverCurrentPosition = position;
      onlineDriverCurrentPosition = position;

      LatLng latLngLiveDriverPosition = LatLng(
        onlineDriverCurrentPosition!.latitude,
        onlineDriverCurrentPosition!.longitude,
      );

       Marker animatingMarker = Marker(
         markerId: const MarkerId("AnimatedMarker"),
         position: latLngLiveDriverPosition,
         icon: iconAnimatedMarker!,
         infoWindow: const InfoWindow(title: "Questa è la tua posizione"),
       );

      setState(() {
        CameraPosition cameraPosition = CameraPosition(target: latLngLiveDriverPosition, zoom: 15);
        newTripGoogleMapController!.animateCamera(CameraUpdate.newCameraPosition(cameraPosition));
        
        setOfMarkers.removeWhere((element) => element.markerId.value == "AnimatedMarker");
        setOfMarkers.add(animatingMarker);
      });

      oldLatLng = latLngLiveDriverPosition;
      updateDurationTimeAtRealTime();

      //updating driver location in realtime in database firebase
      Map driverLatLngDataMap =
      {
        "latitude": onlineDriverCurrentPosition!.latitude.toString(),
        "longitude": onlineDriverCurrentPosition!.longitude.toString(),
      };
      

      FirebaseDatabase.instance.ref().child("ALL Ride Requests")
          .child(widget.userRideRequestDetails!.rideRequestId!)
          .child("driverLocation")
          .set(driverLatLngDataMap);
    });
  }

Code Example for activeDrivers instance (is created only to keep track of the riders who are online at the time and updates its position in real time)

driverIsOnlineNow() async
  {
    Position pos = await Geolocator.getCurrentPosition(
      desiredAccuracy: LocationAccuracy.high,
    );
    driverCurrentPosition = pos;

    Geofire.initialize("activeDrivers");
    
    Geofire.setLocation(
        currentFirebaseUser!.uid,
        driverCurrentPosition!.latitude,
        driverCurrentPosition!.longitude
    );

    DatabaseReference ref = FirebaseDatabase.instance.ref()
        .child("drivers")
        .child(currentFirebaseUser!.uid)
        .child("newRideStatus");

    ref.set("idle"); //searching for ride request
    ref.onValue.listen((event) { });


  }

CodePudding user response:

This construct that you use in many places doesn't do what you expect it to do:

root.child('users/uid').exists()

This checks whether there's a node called /users/uid, so with the literal name/key "uid". You probably want top check if there's a node for the current user's UID, which would be:

".write": "root.child('users').child(auth.uid).exists()
  • Related