Intro
Yesterday, I worked on chrome extension for my personal project. While doing that, I had some troubles regarding to the difference between Chrome Extension Manifest V2 and V3 in terms of using firebase in my extension.
Here, I’d like to share how I solved it.
Manifest V3 setting for Firebase
{
"name": "Linkeeper Chrome Extension",
"description": "Achieve current web link to Linkeeper fast",
"version": "1.0",
"manifest_version": 3,
"host_permissions": [
"<all_urls>"
],
"background": {
"service_worker": "serviceWorker/background.js"
},
"permissions": [
"tabs",
"scripting",
"activeTab",
"identity"
],
"action": {
"default_popup": "view/popup/popup.html",
"default_icon": {
...
}
},
"icons": {
...
},
"oauth2": {
"client_id": "<Your Client Id>",
"scopes": [
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/userinfo.profile"
]
},
"key": "-----BEGIN PUBLIC KEY-----<Your Chrome Extension Public Key>-----END PUBLIC KEY-----"
}
There’re good article about forming your manifest.json in below link.
https://firebaseopensource.com/projects/firebase/quickstart-js/auth/chromextension/readme/
However, It’s somewhat outdated because now we have Manifest V3. When you write your manifest.json in V3 you need to be careful below fields.
-
host_permissions
→ it’s not included in above link’s example, but in V3 you include this -
background
→ instead usingpage
field insidebackground
field, you need to useservice_worker
Other than that, it’s just same.
Background service worker to use Firebase
// serviceWorker/background.js
try {
// you need to manually have firebase-compat.js file in your dir
self.importScripts('../firebase/firebase-compat.js');
var config = {
apiKey: "...",
authDomain: "...",
databaseURL: "...",
projectId: "...",
storageBucket: "...",
messagingSenderId: "...",
appId: "..."
};
firebase.initializeApp(config);
var db = firebase.firestore();
chrome.runtime.onMessage.addListener(function (request, sender) {
if (request.command === "post") {
// in here, you can use both firebase and data from popup view
console.log(request.data);
return true;
}
});
} catch (e) {
console.error(e);
}
In background service worker file, you need to initialize your firebase. In order to to that you need to import firebase first. This was a bit tricky for me since you can’t use background.html script tag to import it or import directly from web url. The answer for Manifest V3 was just copy and paste the code in below link and manually include javascript file to your chrome extension folder.
https://www.gstatic.com/firebasejs/9.6.10/firebase-compat.js
Then, import that file in your service worker with self.importScripts
.
Of course, you may want to interact with user interaction data with firebase. By using chrome.runtime.onMessage.addListenser
in you service worker, and chrome.runtime.sendMessage
in your view script can make that happen. In that way, you can access both user input data and firebase on your service worker file.
//view/popup/script.js
...
chrome.runtime.sendMessage({
command: 'post', data: {
...
}
}, (response) => {
console.log(response);
}
);
...
Conclusion
I think many of your web project will gain more attention when you add chrome extension. I hope that this article will help your journey.
Cheers!
Top comments (10)
But what about Google-authorization, which requires user interaction through a window? Such a window can be called from popup/script.js with the chrome.identity.getAuthToken({ interactive: true }, function (token) {....
But now, logically, this function needs to be placed in serviceWorker/background.js , and there is no way to get a window from background.js in popup/script.js via sendMessage=>(response) ? Or is it still possible?
Before MV3, this was solved by referring to background.js as a constant and its internal procedures as internal constants ( const bg = chrome.runtime.getManifest().background; ), but now it’s not clear how to be.
I used getAuthToken(interactive true) on background.js and triggered from popup/script.js via sendMessage & chrome.runtime.onMessage.addListener. You can pass user authentication information that you need(uid, name etc.) like that. In my case, I just needed to login in order to use firestore.
Could you upload a demo extension that does this to a repo? I'm having a hard time figuring this out and would appreciate any help at all
I can add that it is convenient to get the Firebase config from Firebase / Project settings / Your apps / SDK setup and configuration / radiobutton "Config"
Thank you for this article. Really helped me out as there is so much outdated and confusion information available.
I'm glad that this post helped you!
github for simple implementation?
Hi🫡,
Did you find any workaround for this? We're into the same problem🥲.
Dude, i just can't thank you enough.You are such a lifesaver