0

I have my react app connected to firebase's firestore. I was using firebase's real-time db and this issue didn't occur with it, but now I simply changed my db to firestore and I have this issue. (I didn't change any react code, so it must be something with firestore).

In my appcontainer file I have this:

const [userlist, setUserList] = useState([])
const [invoicesList, setInvoicesList] = useState([])

const oneinvoice = invoicesList && invoicesList.map(oneinv => {
return <Route path={"/invoice/"+oneinv.id}>
  <OneInvoice oneinv={oneinv} /> 
</Route>
})

So every instance of an invoice has a unique path which is equal to: 'invoice'/+"id".

In my app container I fetch my invoices using firestore:

useEffect(() => {
    db.collection("users").doc(user.uid).get().then(doc => {
      const userlist = doc.data() 
      setUserList(userlist) 
      setInvoicesList(userlist.invoices)
    })  
  },[])

And in my invoices UI I have the following:

const invoicerow = invoicesList && invoicesList.map(inv => {  
    return 
        <div className="flexrow"> 
          <h5>{inv.name}</h5>
          <Link to={`/invoice/${inv.id}`}>Open Invoice</Link>
        </div>    
  })

Now my issue is when I click on the "open invoice" which should open that invoice page, it shows up blank but the URL path is good, it has the correct id but nothing displays. Note: When I reload the page suddenly the invoice displays perfectly well and even if I go back and click on the "open invoice" it works. It seems to not work only on the initial creation of the invoice only.

Again this exact code was working perfectly fine with firebase's RTDB, but not now with firestore.

Dominik
  • 4,529
  • 6
  • 34
  • 48
Aviale
  • 81
  • 1
  • 5
  • 2
    I have never seen react-router params used like this. Are you familiar with using a route param like `/:id` and the `useParams` hook? https://reactrouter.com/web/api/Hooks/useparams – Nick Jan 04 '21 at 22:04
  • why then did it work with the RTDB? i tried using /:id - that was worse, it didn't work even afetr reloading the page – Aviale Jan 04 '21 at 22:06
  • It might help if you have a fallback route for now to debug if the route exists (and the data isn't loading), or if instead the route was not created (and maybe dump the `invoicesList`). – Garrett Motzner Jan 04 '21 at 22:23
  • @GarrettMotzner how would i do that? – Aviale Jan 04 '21 at 22:26
  • Also, `/:id` probably can work, if it is implemented right, but it looks different than what are currently doing. You have to add logic to lookup the proper record by id. But that pattern has several advantages and is probably more what you want. – Garrett Motzner Jan 04 '21 at 22:27
  • But none of this answers the question why this worked with firebase RTDB and not with firestore? – Aviale Jan 04 '21 at 22:33
  • The probable reason why it worked in one case and not the other is that you're making a valid route, but it's wrong for what you want it to do. It seems the route will work only when the 'id' matches what it originally was whenever that component is rendered, but it won't work generally for all id's. This is where Nick's and Garrett's comment will come in. Just a word of warning as it has caught me out. If you're 'id' is a number, when using the useParams hook, it will come out as a string, you'll need to check and cast it before using it. – Michael Bauer Jan 04 '21 at 23:30
  • 1
    First, check that `invoicesList` in the routes component is the same as `invoicesList` in the linking component, specifically the `id` property. Second make sure you are constructing the paths the same way and correctly. What debugging have you done on your own to validate/verify your paths/URLs are correct? Can you also include the component code for the page component that requires a reload, and the entire `Router` code/logic? – Drew Reese Jan 04 '21 at 23:41
  • There are a few reasons I can think of why it worked with one db but not the other, and they basically boil down to when the data was made available happens at different times or updates at different times between the two databases. Perhaps one serves data faster, or updates faster, so you didn't see the blank data you did in the other. Or perhaps one does realtime updates and the other doesn't, or you didn't use the same features in both... A diff of changes between the two implementations might help... – Garrett Motzner Jan 05 '21 at 00:34
  • @DrewReese i checked multiple times and i can guarantee both ids are the same. That is the route path id and the link to id are identical. I beleive garett is right, it seems when the component renders, the invoicesList object is not avalable yet. Although that doesn't explain why reloading the page makes it work afterwards. – Aviale Jan 05 '21 at 02:36
  • I suspect the reload doesn't so much fix it as you get lucky the second time, unless you have some sort of cacheing enabled that allows it to load faster the second time. You can [turn caching off](https://stackoverflow.com/questions/5690269/disabling-chrome-cache-for-website-development) in your dev tools and check that, and also [slow down load times](https://stackoverflow.com/questions/48367042/in-chrome-dev-tools-what-is-the-speed-of-each-preset-option-for-network-throttl) to make it more consistently fail. – Garrett Motzner Jan 07 '21 at 17:21
  • As to how to inspect and debug, here's a good place to start: https://developers.google.com/web/tools/chrome-devtools/javascript and https://raygun.com/blog/react-debugging-guide/. Also, you can "dump" a javascript object to a react component sorta like this: `
    {JSON.stringify(foo)}
    `, But that is kinda a kludgey way to do that, and dev tools are more powerful.
    – Garrett Motzner Jan 07 '21 at 17:31

0 Answers0