0

I fetched an array of products from firebase with the normal way :

export const getUsersProducts = async uid => {
    const UsersProducts = []
    await db.collection('products').where("userID", "==", uid).get().then(snapshot => {
        snapshot.forEach(doc => UsersProducts.push(doc.data()))
    })
    return UsersProducts
}

and the fetched array shows up in the dom normally, but when I tried to fetch it with onSnapshot method it didnt show up on the DOM even though in appeared in my redux store and when I console log it, it shows up normally.

export const getUsersProducts = uid => {
    let UsersProducts = []
    db.collection('products').where("userID", "==", uid).onSnapshot(querySnapshot => {
        querySnapshot.docChanges().forEach(change => {
            if (change.type === "added") {
                UsersProducts.push(change.doc.data())
            }
        })
    })
    return UsersProducts
}

here is the code used to show it in the DOM

const MyProducts = () => {
    const CurrentUserInfos = useSelector(state => state.userReducer.currentUserInfos)
    const searchQuery = useSelector(state => state.productsReducer.searchQuery)
    const myProducts = useSelector(state => state.productsReducer.usersProducts)
    const dispatch = useDispatch()
    const settingUsersProductList = async () => {
        try {
        const usersProducts = getUsersProducts(CurrentUserInfos.userID)
        dispatch(setUsersProducts(usersProducts))
        console.log(myProducts)
        } catch (err) {
            console.log(err)
        }
    }
    useEffect(() => {
        settingUsersProductList()
    }, [CurrentUserInfos])
    return (
        <div className="my-products">
            <div className="my-products__search-bar">
                <SearchBar />
            </div>
            <div className="my-products__list">
                {
                    Object.keys(myProducts).length===0 ? (<Loading />) : (myProducts.filter(product => {
                        if(searchQuery==="")
                            return product
                        else if(product.title && product.title.toLowerCase().includes(searchQuery.toLowerCase())) 
                            return product
                    }).map(product => {
                        return(
                            <ProductItem
                                key={product.id}
                                product={product}
                            />
                        )
                    }))
                }
            </div>
        </div>
    )
}

export default MyProducts

1 Answers1

0

You are returning the array before promise is resolved hence its empty. Try this:

export const getUsersProducts = async uid => {
    const snapshot = await db.collection('products').where("userID", "==", uid).get()
    const UsersProducts = snapshot.docs.map(doc => doc.data())
    return UsersProducts
}

For onSnapshot, add the return statement inside of onSnapshot,

export const getUsersProducts = uid => {
    let UsersProducts = []
    return db.collection('products').where("userID", "==", uid).onSnapshot(querySnapshot => {
        querySnapshot.docChanges().forEach(change => {
            if (change.type === "added") {
                UsersProducts.push(change.doc.data())
            }
        })
        return UsersProducts 
    })
}
Dharmaraj
  • 47,845
  • 8
  • 52
  • 84
  • The method - .get() - worked correctly for me, I'm looking to fetch them with onSnapshot method – Adda Younes Jul 23 '21 at 15:26
  • @AddaYounes similar concept ... add the return statement inside of onSnapshot... check updated answer. – Dharmaraj Jul 23 '21 at 15:39
  • Also if it was helpful you can accept it by clicking tick icon beside my answer – Dharmaraj Jul 23 '21 at 15:39
  • I'm not sure where the problem is but I don't think it's in the query, because after I fetch the products I dispatch an action that sets them in my redux store... thus I can see them in my store !! but can't see them in the DOM!! the component appear instead – Adda Younes Jul 23 '21 at 16:23
  • @AddaYounes do you atleast get the data as intended using updated code instead of empty array – Dharmaraj Jul 23 '21 at 16:25
  • as I mentioned in the question's description the data is retrieved normally from the beginning, the problem occurs when trying to show it – Adda Younes Jul 23 '21 at 16:32