18
votes

I'm trying to render some rows from firebase database, I'm getting this error:

TaskQueue: Error with task : Invariant Violation: Tried to get frame for out of range index NaN

  const { currentUser } = firebase.auth();
    var userfavorites = firebase.database().ref(`/users/${currentUser.uid}/favorites/`);
    userfavorites.once('value').then(snapshot => {
      this.setState({ userfav: snapshot.val() })
    })

...

  <FlatList
    data={this.state.userfav}
    renderItem={({ item }) => (
      <Text>{item.favdata}</Text>
    )}
  />

DB Structure

4

4 Answers

8
votes

I came across this error, I had a PHP back-end and trying to get json_encoded data into a FlatList.

Problem: The REST endpoint was returning an object eg

{"Total_Excavator":2,"Active_Excavator":2,"Total_load":6804}

Solution: Fixed it to return an array rather eg

[{"Total_Excavator":2,"Active_Excavator":2,"Total_load":6804}]

Take note of the Square Brackets. I used $data[] = json_encode($excavatorArray) instead of $data = json_encode($excavatorArray) . Hope it helps someone one day

4
votes

I had the same issue, it seems this problem is the reason of the object names. In the image below you can see that as soon as you fetch snapshot from Firebase endpoint it comes with the id which is not recognized by React Native. And react acts like it's empty obj. firebase returned snapshot

All you have to do is map the items of the object after fetching it like example below,

const fbObject = snap.val();
const newArr = [];
Object.keys(fbObject).map( (key,index)=>{
    console.log(key);
    console.log("||");
    console.log(index);
    newArr.push(fbObject[key]);
});
2
votes

Just a slight modification to the answer from @mert. JavaScript's map operator returns an array; so, there is no need to push elements onto newArr. Also, the new array's elements are going to be missing the unique Firebase id. So, it should be added into the array element.

const fbObject = snapshot.val();
const newArr = Object.keys(fbObject).map((key) => {
  fbObject[key].id = key;
  return fbObject[key];
});

You'll end up with a newArray like this:

[
  {
    "id": "12345",
    "name": "Jane Doe",
    "age": 18
  },
  {
    "id": "23456",
    "name": "John Smith",
    "age": 27
  }
]
1
votes

I had a similar problem and saved the flatlist's data in the state. You have to make sure that the data in the state is a list instead of an object:

this.state = {
    ...,
    data: [], // <-- wrap your flatlist's data in there
}

When making changes to your data/the state, always use the callback function to perform something afterwards to keep your UI in sync:

this.setState({..., data}, () => yourCallback())