Home > Software design >  Returning real time data from firebase using onSnapshot and rtk query
Returning real time data from firebase using onSnapshot and rtk query

Time:07-07

I am trying to return real time data from firebase using onSnapshot rtk query but it is not working rtkquery code (apiSlice.js)

export const apiSlice = createApi({
  reducerPath:'api/apiSlice',
  baseQuery: fakeBaseQuery(),
   endpoints: builder => ({
    getPosts: builder.query<Posts[],void>({
      async queryFn():Promise<any>{
        try{
          //const tweetsRef=collection(db,'tweets');
          let tweetsArr: { }[];
          onSnapshot(collection(db,'tweets'),(querySnapshot)=>{
           tweetsArr=querySnapshot.docs.map((doc)=>{
            console.log(doc.data());
               return {...doc.data()}
            })
        })
           return {data:tweetsArr} 
        }
        catch(err:any){
          return{error:err} 
        }
    }})  
})
})

export const { useGetPostsQuery, useAddPostMutation } = apiSlice

When returning the data I am getting an error saying 'Variable 'tweetsArr' is used before being assigned.'

Trying to access the data

const PostsList = () => {
  const {data:posts,isLoading,error,isError} = useGetPostsQuery();
 
  let content;

  if(isLoading){
    content=<LoadingSpinner/>
  }

  else if(isError){
      let a:any=error
      content=<p>{a?.message}</p>
  }

  else if(posts){
    console.log(posts)
    content=posts?.map((post,index) => (
      <Post key={index} {...post}/>
    ))
  }

  return (
    <section className="posts-list">
    {content}
    </section>
  )
}

CodePudding user response:

onSnapshot() listener can only return within the method.

Sample code below:

try{
    let tweetsArr = [];
    onSnapshot(collection(db,'tweets'),(querySnapshot)=>{
    tweetsArr=querySnapshot.docs.map((doc)=>{
         tweetsArr.push(doc.data());
         console.log('correct', tweetsArr);
      })
      console.log('wrong', tweetsArr);
    })
  }catch(error){
    console.log(error); 
  }

Output:

enter image description here

You can use onSnapshot() to listen to the results of a query. Listen to multiple documents in a collection you may refer to this link.

CodePudding user response:

Used a promise to solve the problem

let tweetsArr: { }[]=[];
          return new Promise((resolve, reject) => {
            onSnapshot(collection(db,'tweets'),(querySnapshot)=>{
              tweetsArr=querySnapshot.docs.map((doc)=>{
               console.log(doc.data());
                  return {...doc.data()}
               })
               console.log(tweetsArr);
               resolve({data:tweetsArr});
            })})
  • Related