I get duplicate data from Firestore after adding data. In React Native

Viewed 188

I am using React Native and Firestore for my application. I use onSnapshot() for retrieving data from Firestore. I don't have problems with retrieving data, but after I add a new user it adds the new user and also the existing data. For example I have 5 users in my list and I add one user. After adding It must be six users, but I got 11 users instead of 6.

Therefore I get this error: "Encountered two children with the same key..."

And also if I edit the data via the Firestore manually I don't get the changes, For example if I Change the name James to Mike, it is not changing, only if I reload the application.

The weird thing is that it first worked and after few days when I start to work on the project again, I got this bug.

const userCol = firestore.collection("tblUser"); 
const [users, setUsers] = useState([]);

This is my function to get data from Firestore:

  useEffect(() => {
    const getUsersFromDB = [];

    const getData = userCol.onSnapshot((snapshot) => {
      snapshot.forEach((doc) => {
        getUsersFromDB.push({
          ...doc.data(), id: doc.id
        });
      });
      console.log("array size: " + users.length)
      setUsers(getUsersFromDB)
      setLoading(false)
    })

    return () => getData()

  }, [loading])

  if (loading) {
    console.log("loading data")
    console.log("array size: " + users.length)
  }

This is the console.log after the first time I opened the screen:

enter image description here

The console.log after I added a user, first the size of the array was 13 after adding one user it was 27:

enter image description here

This is my function to add a user:

  const addUser = () => {
    {/* 
     Some of the fields are empty because they are not necessary
    */}
    userCol.add({
      image: (a link of the image in firestore),
      firstName: userFirstname,
      lastName: userLastname,
      email: userEmail,
      password: userPassword,
      function: "",
      isAdmin: false,
      phoneNumber: "",
      label: userLabel,
      hobby: "",
      startDate: firebase.firestore.FieldValue.serverTimestamp(),
    }).then(() => {
      console.log("user addded" + userFirstname + " " + userLastname)
      console.log("array size: " + users.length)
    }).catch((error) => {
      console.log("error: " + error)
    });

  }

code of the list:

      {/* List of users */}
      <View style={styles.userList}>
        <ScrollView showsVerticalScrollIndicator={false}>
          {
            users.map((user) => (
              <ListItem key={user.id} bottomDivider>
                <Avatar source={{ uri: user.image }} />
                <ListItem.Content>
                  <ListItem.Title>{`${user.firstName} ${user.lastName}`}</ListItem.Title>
                  <ListItem.Title>{"id: " + user.id}</ListItem.Title>
                </ListItem.Content>
                <Icon name='delete' color="#0A355E" onPress={() => deleteUser(user.id)} />
              </ListItem>
            ))
          }
        </ScrollView>
      </View>

The code of the button for adding a user:

{/* creates new user */}
                <Button style={styles.button}
                  onPress={() => {
                    addUser()
                      + setTimeout(() => {
                        Alert.alert(userFirstname + " " + userLastname + " is added")
                      }, 2000) + setModalVisible(false) + console.log("array size: " + users.length)

                  }}
                >
                  <Text style={styles.buttonTxt}>Creëer</Text>
                </Button>

I know that there are questions almost the same as mine, but the solutions did't helped me. I also tried to empty the array before adding a user, but it did not help.

Thanks

1 Answers

Your code is using a snapshot to pull all the documents in the collection, and add these to the array getUsersFromDB.

So for the case you mention:

For example I have 5 users in my list and I add one user.

You code will

  1. pull the 5 users and add them to getUsersFromDB
  2. once you have added 1 user, it will pull all 6 of them and add them to getUsersFromDB

Which is what you experience:

After adding It must be six users, but I got 11 users instead of 6.

To avoid duplicates you can:

The first one is the cleanest but you should implement both to be on the safe side.

Related