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
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.