Home > Back-end >  Flutter FirebaseFirestore: retrieving fields from an array of IDs
Flutter FirebaseFirestore: retrieving fields from an array of IDs

Time:12-16

I'm trying to retrieve fields from multiple IDs that are stored in an array. I have a collection of users, and in every user's document, there is an array of restaurant IDs of that user's owned restaurant as follows:

enter image description here

And each restaurant's document is one of those IDs in the array. I successfully retrieved the array of ID's from the User but now I'm trying to get the names of the restaurant depending on the ID

enter image description here

I'm retrieving my ID's using this code:

  var restaurantIDs = [];
      
  getRestaurantIDs() async {
    await FirebaseFirestore.instance
        .collection("users")
        .doc(user.uid)
        .get()
        .then((value) {
      restaurantIDs = value.data()['rid'];
    });
    return restaurantIDs;
  }

Then I'm trying to retrieve the names and save them in an array using this code:

  var restaurantNames = [];

  getRestaurantNames() async {
    for (int i = 0; i < restaurantIDs.length; i  ) {
      await FirebaseFirestore.instance
          .collection('restaurant')
          .doc(restaurantIDs[i])
          .get()
          .then((value) {
        restaurantNames = value.data()['name'];
      });
    }
    return restaurantNames;
  }

What am I doing wrong? and thanks for the help.

EDIT:

1- I tried placing print statements inside the for loop, but it's like as if it's not going inside the loop at all, because the print statements don't get executed.

2- I think it's because the list of IDs won't be already stored inside the array when the function is called inside the initState, because I tried to print the length of the restaurantIDs array before the for loop and in initState and it showed 0, but when I print it inside the Scaffold, it would show 2.

EDIT 2:

I tried merging both functions into one to make sure that the restaurantIDs isn't empty, and now it goes inside the for loop because it prints out the statement, but now I receive another error

new function:

var restaurantIDs = [];
  var restaurantNames = [];

  getRestaurantIDs() async {
    await FirebaseFirestore.instance
        .collection("users")
        .doc(user.uid)
        .get()
        .then((value) {
      restaurantIDs = value.data()['rid'];
    });
    for (var i = 0; i < restaurantIDs.length; i  ) {
      print('added one');
      await FirebaseFirestore.instance
          .collection('restaurant')
          .doc(restaurantIDs[i])
          .get()
          .then((value) {
        restaurantNames.add(value.data()['name']);
      });
    }
    return restaurantNames;
  }

Error:

E/flutter (22920): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: NoSuchMethodError: The method '[]' was called on null.
E/flutter (22920): Receiver: null
E/flutter (22920): Tried calling: []("name")
E/flutter (22920): #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:68:5)
E/flutter (22920): #1      _AddMealScreenState.getRestaurantIDs.<anonymous closure>
package:bits_n_bobs/screens/add_meal_item_screen.dart:178
E/flutter (22920): #2      _rootRunUnary (dart:async/zone.dart:1436:47)
E/flutter (22920): #3      _CustomZone.runUnary (dart:async/zone.dart:1335:19)
E/flutter (22920): <asynchronous suspension>
E/flutter (22920): #4      _AddMealScreenState.getRestaurantIDs
E/flutter (22920): <asynchronous suspension>
E/flutter (22920):

CodePudding user response:

restaurantNames.add( value.data()['name']);

?

CodePudding user response:

There is something a bit off about the way you have organized your database. For each restaurant document, you should create a key with the user id as value, and then simply use the where query.

Example :

final restaurants = await FirebaseFirestore.instance.
        .collection("restaurant")
        .where("userId", isEqualTo: user.uid);            
        .get()

You can then map the retrieved list and filter the restaurant's name from it.

 final restaurantNames = data.docs
      .map((json) => 
            json.data()["name"])
      .toList();

Hope's that is hopefull.

  • Related