Tristan Kay
Tristan Kay

Reputation: 11

StreamBuilder arrayContains and RangeError (index): Invalid value: Valid value range is empty: 0

Slowly getting to grips with Flutter and Dart as my new hobby. Any advice or help you can give is always appreciated! I am trying to implement a simple friend system, where you can search for another user and add them as a friend.

The intended outcome is:

  1. Logged in user goes to profile of friend and clicks 'add friend' button.
  2. Firestore has a users collection. In that collection is a document for each user with profile information, including an array 'friends'. Clicking the 'add friend' button will add the logged in users UID to that second person's 'friends' array.
  3. Then on a Friends screen, I am using a StreamBuilder and Listview.builder to show all users as cards, that have the logged in user's UID in their 'friends' array.

To achieve this, I want to use .where('friends', arrayContains: 'user.uid') in stream of StreamBuilder, to only show those user cards in the list on the screen.

Here is the code I have written:

class friendsList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final user = Provider.of<User>(context);

    return 
      StreamBuilder(
      stream: Firestore.instance
              .collection('users')
              .where('friends', arrayContains: user.uid).snapshots(),
               builder: (context, documents) {

               if (documents.hasData) {
               return 

               Container(
                    height: 180,
                        child:

                            ListView.builder(
                               scrollDirection: Axis.horizontal,
                               itemCount: 1,
                               itemBuilder: (context, index) {

                               DocumentSnapshot friends = documents.data.documents[index]; 

However, when I go to run my app, it shows error:

`The following RangeError was thrown building:
      RangeError (index): Invalid value: Valid value range is empty: 0

      When the exception was thrown, this was the stack 
        List.[](dart:core-patch/growable_array.dart:149:60)
        friendsList.build.<anonymous closure>.<anonymous closure> 

Notes:

  1. itemCount is hardcoded to 1 right now. I am only expecting 1 user to be returned while I am testing. I will populate Firestore with more users once it is all working.
  2. When I swap arrayContains for something simpler like .where('displayName', isEqualTo: 'My Name').snapshots(), , the app works without errors
  3. user.uid has been tested and does contain the intended string
  4. Arrays are present with values in Firestore (See link at bottom of post)
  5. I have setup an index for the values I am using in 'users'

Does anyone know what I can do about this error and retrieve the documents that have the friends array with the logged in user UID?

Again any advice and help is appreciated. Screenshot of Cloud Firestore is here

Upvotes: 0

Views: 1246

Answers (2)

MrSnave
MrSnave

Reputation: 1

It could be the case that you are printing the results of an empty data from firebase.

Stream<List<Model>> fetchStream({@required String userUID}) {
return nestsCollection
    .where("participants", arrayContains: userUID)
    .snapshots()
    .map((snapshot) {
    // print(snapshot.docs[0].data()['nestName']);
  return snapshot.docs
      .map((document) => Model.fromFirestore(document))
      .toList();
 });
}

Upvotes: 0

Tristan Kay
Tristan Kay

Reputation: 11

I left my project for two days and rebuilt the app in the last hour. To my surprise, '.where('friends', arrayContains: user.uid)' now works!

When the app starts, I now have a ListView of all users who are a friend of the currently logged in user.

How the complete system works:

  1. On the profile page of each user is a Floating Action Button that when pressed, add's the currently logged in user's UID to a 'friends' array in the document of that friend.

  2. With StreamBuilder and ListView, when the logged in user then goes to their friends page, they see every user that has the logged in user's UID in their 'friends' array

Upvotes: 1

Related Questions