0

Im building a chrome extension and need to get data from google cloud firestore in background.js before sending the returned data as a message to popup.js.

This is what background.js looks like:

  //background.js

  chrome.runtime.onMessage.addListener((msg, sender, resp) => {
    if (msg.command == 'fetch') {
      const listData = fetchListTitles();
      resp({
        type: 'result',
        status: 'success',
        data: listData,
        request: msg,
      });
      return true;
    }
  });
} catch (e) {
  console.error(e);
}

//get firestore data function
const fetchListTitles = async () => {
    let listTitles = [];
    const q = query(
      collectionGroup(db, 'Lists'),
      where('author', '==', 'placeholder')
    );

    const temp = await getDocs(q);

    temp.docs.map((doc) => {
      listTitles.push(linksToJSON(doc));
    });
    console.log(listTitles);
    return listTitles;
  };

This is what popup.js looks like

  //popup.js
  chrome.runtime.sendMessage({ command: 'fetch' }, (resp) => {
      if (resp.data) {
        console.log('popup', resp);
        setListTitles(resp.data);
      }
    });

When I read out or console.log the data returned, I do not see any data returned from friestore. However, in background.js I can see the returned data that I console.log from the fetchListTitles function

1 Answers1

1

fetchListTitles is declared with async keyword which means it always returns a Promise.
Chrome extensions can't send Promise via messaging.

You need to send the response after the Promise is fullfilled:

chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  if (msg.command === 'fetch') {
    fetchListTitles().then(listData => sendResponse({
      type: 'result',
      status: 'success',
      data: listData,
      request: msg,
    }));
    return true; // keeps the channel open for sendResponse
  }
});

See also why Chrome extensions can't use async/await in onMessage directly.

wOxxOm
  • 65,848
  • 11
  • 132
  • 136