firebase / firebase-js-sdk

Firebase Javascript SDK
https://firebase.google.com/docs/web/setup
Other
4.75k stars 872 forks source link

onSnapshot unresponsive to changes in database #8245

Closed cb92 closed 2 weeks ago

cb92 commented 2 weeks ago

Operating System

Mac OS Sonoma

Browser Version

Chrome/124.0.6367.158

Firebase SDK Version

Admin Node.js 12.1.0

Firebase SDK Product:

Firestore

Describe your project's tooling

Node js app to build a bar chart using some d3.js.

Describe the problem

I am trying to dynamically update a d3.js barchart based on a Firestore database using the onSnapshot function in my node.js app. The connection seems to be working in general, as the app does correctly pull the data and render the chart the first time it is opened, but it does not update as expected when I delete/change/add data to Firestore database in the browser.

Steps and code to reproduce issue

Get route from index.js file

app.get('/', (req, res) => {
  const unsubscribe = db.collection('dishes').onSnapshot(snapshot => {
    const documents = [];
    snapshot.forEach(doc => {
      documents.push(doc.data());
    });

    const documentsJSON = JSON.stringify(documents);
    res.render('barchart',  { documentsJSON }); // Pass data to the template
  }, err => {console.log("error!");
});

  // detach listener
  req.on('close', () => {
    unsubscribe();
  });
});

Data is then processed using code in render_code.js, which is embedded in the handlebars as follows:

  <script type="text/javascript" src = '/render_code.js' data-documents='{{{documentsJSON}}}'>
  </script>
tom-andersen commented 2 weeks ago

Hi @cb92

It looks like you are using Express to render the result, and the browser simply receives static HTML. See: https://expressjs.com/en/guide/using-template-engines.html

A more complete reproduction of problem might be helpful.

Does your architecture support updates? Meaning, if instead of using onSnapshot, you use setTimeout to call render with different documents, does it work?

It also sounds like you might be using the Admin SDK? In which case, you should direct your question here:

https://github.com/firebase/firebase-admin-node

or here for Firestore Server SDK

https://github.com/googleapis/nodejs-firestore

The SDK in this repository can be used to run a Firestore client on the browser (as opposed to NodeJS Express server). If you do that, you will find onSnapshot can update, because the page is rendered client side, instead of server side through Express server where I suspect static HTML is rendered, and passed to browser (incapable of being updated after it has been sent).

I hope that helps.

cb92 commented 2 weeks ago

You're right - I didn't realize that Firebase SDK didn't play nice with server side code. Modifying the code to be client-side does indeed fix the issue, thank you so much for the help!