Stack Exchange
Grabbing the wrong item from firebase realtime database via react native expo
Another method I tried apart from Issue with firebase realtime DB, equalTo() with react native expo  (Reference from https://www.youtube.com/watch?v=C4ZnTCi50bc for the equalTo() part)
My code
const SubScreen2 = () => {
  
  
  const navigation = useNavigation()
  
  const [todoData, setToDoData] = useState([])
  
  
  useEffect (() => {
    var random = 0
    get(ref(db, "food/Total")).then(snapshot => {
      const count = snapshot.val();
      console.log(count)
      random = Math.floor((Math.random() * count));
      console.log(random)
      const rc = query(ref(db, `food/`), orderByChild("ShopNo"), equalTo(random))
      get (rc)
      .then ((snapshot) => {
        const data = snapshot.key
        console.log(data)
      })
      
      
    
      
  },) })

And adding the rules to the database as the terminal tells me to add as there is missing rules:

But the output I get for data is food

The first log is the total number of shops I have in the database. The 2nd log is the randomize value of the 1st log while the 3rd log is for the snapshot.key of the ShopNo that has the 2nd log value
My intention is to grab the Shop node that has the ShopNo of the 2nd log but now it is grabbing the database name that is food. What am I doing wrong?
Part of my database:

{
  "Bakery": {
    "Bakery Cuisine": {
      "Description": "Within North Spine Plaza",
      "Halal": "Yes",
      "Latitude": 1.34714,
      "Location": "50 Nanyang Ave, #01-20 North Spine Plaza, Singapore 639798",
      "Longitude": 103.68066,
      "OH": "Mon - Sat : 8 AM to 7 PM, Sun Closed",
      "ShopNo": 1
    }
  },
  "Beverage": {
    "Beverage": {
      "Description": "Within the South Spine food court",
      "Halal": "No",
      "Latitude": 1.34253,
      "Location": "21 Nanyang Link, Singapore 637371",
      "Longitude": 103.68243,
      "OH": "Mon - Fri: 7 30 am to 8 pm, Sat - Sun/PH Closed",
      "ShopNo": 2
    },
    "Beverages": {
      "Description": "Within North Spine Koufu",
      "Halal": "No",
      "Latitude": 1.34708,
      "Location": "76 Nanyang Dr, #02-03 North Spine Plaza, Singapore 637331",
      "Longitude": 103.68002,
      "OH": "Mon - Fri : 7 am to 8 pm, Sat : 7 am to 3 pm, Sun Closed",
      "ShopNo": 3
    },
    "Boost": {
      "Description": "Within North Spine Plaza",
      "Halal": "No",
      "Latitude": 1.34735,
      "Location": "50 Nanyang Ave, #01-11 North Spine Plaza, Singapore 639798",
      "Longitude": 103.68036,
      "OH": "Mon - Fri : 10 am to 9 pm, Sat - Sun: 10 am to 6 pm",
      "ShopNo": 4
    },
"Total": 89,
}

Update: Using Method 1 provided
Code:
const SubScreen2 = () => {
  
  
  const navigation = useNavigation()
  
  const [todoData, setToDoData] = useState([])
  
  
  useEffect (() => {
    var random = 0
    get(ref(db, "food/Total")).then(snapshot => {
      const count = snapshot.val();
      console.log(count)
      random = Math.floor((Math.random() * count));
      console.log(random)
      const rc = query(ref(db, `food/`), orderByChild("ShopNo"), equalTo(random))
      get (rc)
      .then((querySnapshot) => {
        querySnapshot.forEach((shopSnapshot) => {
          const shopKey = shopSnapshot.key;
          console.log("Hello")
          console.log("Randomly selected shop: " + shopKey)
          const shopData = shopSnapshot.val();
          console.log("Shop data", shopData);
        })
      })
      .catch(error => {
        console.log(error);
      })
      
      
    
      
  },) })

No errors reported in console but the only logs I get was

I tried catching the error but there was nothing appearing in my log. I am very confused about this. Why is there no error but at the same time, it cannot grab the node?
Method 2 (Helper Method)
Code
const SubScreen2 = () => {
  
  
  const navigation = useNavigation()
  
  const [todoData, setToDoData] = useState([])
function getFirstChild(queryRef) {
  return get(query(queryRef, limitToFirst(1))) // mix in a query limit
    .then((querySnapshot) => {
      let firstChild = null;
      querySnapshot.forEach((childSnapshot) => {
        firstChild = childSnapshot;
      });
      return firstChild; // DataSnapshot | null
    });
}
  
  
  useEffect (() => {
    var random = 0
    get(ref(db, "food/Total")).then(snapshot => {
      const count = snapshot.val();
      console.log(count)
      random = Math.floor((Math.random() * count));
      console.log(random)
      const rc = query(ref(db, `food/`), orderByChild("ShopNo"), equalTo(random))
      
  getFirstChild(rc) // rc being query(ref(db, "food"), orderByChild("ShopNo"), equalTo(random))
  .then((shopSnapshot) => {
    const shopKey = shopSnapshot.key;
    console.log("Randomly selected shop: " + shopKey)
    const shopData = shopSnapshot.val();
    console.log("Shop data", shopData);
  })
    })
  })

      
      
    
      
  },) })

I got a error of


This answer works when your shop data is nested directly under /food. i.e. "food/XXX": { /* shop data */ }

The below line builds a DatabaseReference:
ref(db, "food/Total")

When you execute get() on a DatabaseReference, the DataSnapshot returned is the data under that reference. In this situation, snapshot.ref will return ref(db, "food/Total") and snapshot.key will return "Total".
The below line builds a Query:
query(ref(db, "food"), orderByChild("ShopNo"), equalTo(random))

When you execute get() on a Query, the DataSnapshot returned contains the subset of data under the given reference that matches the query. In this situation, snapshot.ref will return ref(db, "food") and snapshot.key will return "food".
To get the data returned by the query, you need to make a call to snapshot.forEach to extract the result from "the children of the query snapshot":
get(rc) // rc being query(ref(db, "food"), orderByChild("ShopNo"), equalTo(random))
  .then((querySnapshot) => {
    querySnapshot.forEach((shopSnapshot) => {
      const shopKey = shopSnapshot.key;
      console.log("Randomly selected shop: " + shopKey)
      const shopData = shopSnapshot.val();
      console.log("Shop data", shopData);
    })
  })


You could also expand this logic into its own helper method:
function getFirstChild(queryRef) {
  return get(query(queryRef, limitToFirst(1))) // mix in a query limit
    .then((querySnapshot) => {
      let firstChild = null;
      querySnapshot.forEach((childSnapshot) => {
        firstChild = childSnapshot;
      });
      return firstChild; // DataSnapshot | null
    });
}

Which would be used like so:
getFirstChild(rc) // rc being query(ref(db, "food"), orderByChild("ShopNo"), equalTo(random))
  .then((shopSnapshot) => {
    const shopKey = shopSnapshot.key;
    console.log("Randomly selected shop: " + shopKey)
    const shopData = shopSnapshot.val();
    console.log("Shop data", shopData);
  })

You could also make a getRandomChild(parentRef, indexKey, totalKey) method which could be called using something like getRandomChild(ref(db, "food"), "ShopNo", "Total").

Thanks for the long and detail explanation! I tried to use the 1st code but I cant seem to get any logs out of it. I even added in a console log to print "Hello" but it is also not printed in my logs. The only logs I have is the Total value and the randomize value of Total. Why is this happening? I also tried the 2nd method (Helper method), it gives me the error of null is not an object (evaluating 'shopSnapshot.key')

I have updated the post with what happen after each method

I tried catching the error but there was no error logs in my console. I am very confused about this

As the question seems long, I transferred the update to another question so it wont be long: https://stackoverflow.com/questions/75633268/trouble-with-retrieving-specific-node-in-firebase-realtime-db-via-react-native-e
