Home > Net >  Rtk query not updating properly
Rtk query not updating properly

Time:08-19

I am creating a twitter clone using firebase with rtkquery. I haven't really seen anyone using rtkquery with firebase and i had to use a promise to resolve the data otherwise i was not getting the data

return new Promise((resolve, reject) => {
            onSnapshot(q,(querySnapshot)=>{
              tweetsArr=querySnapshot.docs.map((doc)=>{
               console.log(doc.data());
                  return {id:doc.id,
                    ...doc.data()}
               })
               console.log(tweetsArr);
               resolve({data:tweetsArr});
            })})

I use this function in my apiSlice to get the posts for the index page. The problem is if i navigate to the profile page and refresh it and then navigate back to the index page i get the data of the profile page (getRetweetedPosts()) on the index page rather than the (getPosts()). I consoled.log() and checked and i seem to be going in the right function in api slice (getPosts()) but it is resolving to the previous data of the profile page (getRetweetedPosts()) which is then displayed on the index page and then the righ data is resolved which i know because i am using console.log for everything but it is not displayed only when i refresh the page is it displayed.

apiSlice getPosts

export const apiSlice = createApi({
  reducerPath:'api/apiSlice',
  baseQuery: fakeBaseQuery(),
  // The "endpoints" represent operations and requests for this server
  tagTypes: ['Posts','Users','RetweetPosts'],
  endpoints: builder => ({
    
    getPosts: builder.query<Posts[],void>({
      async queryFn(currUserId):Promise<any>{
        try{

          let currUserDocRef = doc(db,`users/${currUserId}`);
          let docData=(await getDoc(currUserDocRef)).data();
          //console.log(docData);
          let followingsArr=docData?.following??[];
          followingsArr.push(currUserId);
          //console.log(followingsArr);
          let tweetsArr: { }[]=[];
          const q=query(collection(db,'tweets'), where("creatorId", "in" , followingsArr))
          return new Promise((resolve, reject) => {
            onSnapshot(q,(querySnapshot)=>{
              tweetsArr=querySnapshot.docs.map((doc)=>{
            //   console.log(doc.data());
                  return {id:doc.id,
                    ...doc.data()}
               })
              // console.log(tweetsArr);
               resolve({data:tweetsArr});
            })})
        }

        catch(err:any){
          return{error:err} 
        }

    },providesTags: ['Posts']})


getRetweetedPosts

getRetweetedPosts: builder.query<Posts[],void>({
    async queryFn(currUserId):Promise<any>{
      try{

        let tweetsArr: { }[]=[];
        const q=query(collection(db,'tweets'), where("retweetedBy", "array-contains" , currUserId))
        return new Promise((resolve, reject) => {
          onSnapshot(q,(querySnapshot)=>{
            tweetsArr=querySnapshot.docs.map((doc)=>{
             //console.log(doc.data());
                return {id:doc.id,
                  ...doc.data()}
             })
             //console.log(tweetsArr);
             resolve({data:tweetsArr});
          })})
  
      }

      catch(err:any){
        return{error:err} 
      }

  },providesTags: ['RetweetPosts']}),

CodePudding user response:

onSnapshot is the wrong tool here. onSnapshot will not be called once, but it will keep running and re-execute again and again every time you get new data. Your queryFn on the other hand will only run once - and also the Promise you create there can only resolve once. That means you do create a memory leak (data will hang around forever since the onSnapshot listener will not unsubscribe) with no benefit.

You probably should use something that gets that data once from firebase instead - like getDoc. That will also be easier to use.

async queryFn(currUserId) {
      try{

        let tweetsArr: { }[]=[];
        const q=query(collection(db,'tweets'), where("retweetedBy", "array-contains" , currUserId))
        const querySnapshot = await getDocs(q)
        const data = querySnapshot.docs.map((doc)=> ({id: doc.id, ...doc.data()}))
        return { data }
      catch(err:any){
        return{error:err} 
      }
  • Related