1

I am successfully querying Firestore documents with a timestamp earlier than the current date like so:

import React from 'react'
import CircularProgress from '@material-ui/core/CircularProgress'
import { useSelector } from 'react-redux'
import { useFirestoreConnect } from 'react-redux-firebase'
import Grid from '@material-ui/core/Grid'

function MeetingHistory({ userId }) {

    const todaysDate = new Date()

    useFirestoreConnect([
        { collection: 'users', 
          doc: userId,
          subcollections: [{  collection: 'scheduled', 
                              where: [
                                  ['date', '<', todaysDate],
                              ]
                          }],
            storeAs: `${userId}-history-scheduled`
        }
    ])
    const pastMeetings = useSelector(state => state.firestore.ordered[`${userId}-history-scheduled`])

    if (!pastMeetings) return (
        <Grid container direction='row' alignItems='center' justify='center'>
            <CircularProgress />
        </Grid>
    )
    console.log('meetings', pastMeetings)

    return (
        <div>
            <p>I am going to render past meeting data here</p>
        </div>
    )
}

export default MeetingHistory

However, console.log('meetings', pastMeetings) is printing constantly leading me to believe that since the current date is constantly updating as time passes, my database is getting queried every second. This makes sense seeing that new Date() is constantly changing, but I don't want this behavior. I am looking for a way to take a snapshot of the time that won't keep changing with time and base my query off that. Any solution to this would be greatly appreciated. My goal is simply to avoid querying as often as time passes.

Grant Singleton
  • 1,611
  • 6
  • 17
  • You can't pass a variable value to a query. The fact that the date changes over time isn't going to cause a query to change its results based on that changing value. Once you provide a value to a query, that value will never change from the perspective of the query. You would have to issue another query in order to get the date to change. – Doug Stevenson May 21 '20 at 21:00
  • I've never heard that you cant use a variable in a query. Even in the redux firebase docs they show an example of a variable being used in a query. My query is executing constantly when I use new Date(). If I use new Date('hardcode a date here') then it only executes once as expected. The reason I posted this question was because I considered it abnormal, but the query is definitely executed continuously when I use new Date() – Grant Singleton May 21 '20 at 22:57
  • 1
    You can pass the contents of a variable, but its value can't change during the query. It takes the value at the time it was passed. If the variable changes value later, that has no effect on the query. You would have to repeat the query with a new value if you wanted new results. Are you actually repeating this query? Maybe add some debug logging? – Doug Stevenson May 21 '20 at 23:12
  • We need more context - where is this code located? We have no idea *how* it is being called. Is it being called inside a loop? Inside a component? The example given is just painfully incomplete. – LeadDreamer May 22 '20 at 00:21
  • I've updated the code snippet to include the entire component. I want to highlight that there is no issue when I use ```new Date('2020-05-20T21:11:54')```. In that case it only runs once. The issue is only when I use ```new Date()```. I think it has something with React re-rendering the component since the current date is constantly changing but that's the only thing I can think of. – Grant Singleton May 22 '20 at 00:37
  • 1
    Have you tried to indicate the current time programatically `var todaysDate = Date.now();` instead of creating a Date object with `Date()`... – Juancki May 22 '20 at 08:28
  • That did not end up helping but thank you for the idea. I ended up using a regular Firestore query instead of doing it through Redux and it worked fine. It seems to be an issue with Redux useFirestoreConnect hook. – Grant Singleton May 22 '20 at 15:53

1 Answers1

1

I doubt anyone is curious but if they are here is what works. Using a regular Firestore query:

    const todaysDate = new Date()
    const [pastMeetings, setPastMeetings] = useState(null)

    useEffect(() => {
        const db = firebase.firestore()
        db.collection('users').doc(userId).collection('scheduled').where('date', '<=', todaysDate).limit(15)
        .get()
        .then(snap => {
            var temp = []
            snap.forEach(doc => {
                temp.push(doc.data())
            })
            setPastMeetings(temp)
        })
        .catch(err => {
            console.log('error', err)
        })
    }, [userId])

    if (!pastMeetings) return (
        <Grid container direction='row' alignItems='center' justify='center'>
            <CircularProgress />
        </Grid>
    )
    console.log('meetings', pastMeetings)

This runs once as expected. I am thinking that there must have been an issue with my use of useFirestoreConnect or an issue with redux-firestore. Also, I had to run this inside of useEffect() of course, since updating state in the query would cause infinite re-renders. I was not able to call useFirestoreConnect inside useEffect() since you cant use a hook inside of a callback.

Grant Singleton
  • 1,611
  • 6
  • 17