Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save cheadrian/8424217dda5a28724f290eef7fb4e059 to your computer and use it in GitHub Desktop.
Save cheadrian/8424217dda5a28724f290eef7fb4e059 to your computer and use it in GitHub Desktop.
Insert Firebase inside website using Chrome Extension with Manifest V3. Web Version 9 CDN modular Firebase Firestore local JS.

Chrome Extension Manifest V3 Firebase Javascript direct website inject

Updated: 12.Feb.2024

MV3 doesn't support remote hosted code anymore so everything should be bind inside extension package.

Save Firebase Javascript modules inside /js/firebase/ of extension root.

E.g. files: https://www.gstatic.com/firebasejs/10.8.0/firebase-app.js

https://www.gstatic.com/firebasejs/10.8.0/firebase-firestore.js

⚠️ Modify all firebase JS files to ensure all imports are from extension package, as remote script inserting is not allowed anymore in Manifest V3.

E.g. for this case firebase-firestore.js at end of line #1 :

from 'https://www.gstatic.com/firebasejs/10.8.0/firebase-app.js' 
to 
from './firebase-app.js';

Then add firebase_config.js from below to the same folder /js/firebase.

Add inject.js inside root of package.

//This file will be injected before body tag.
//Add file to src or modify path accordingly in manifest.json
import { initializeApp } from "./firebase-app.js";
import { getFirestore, collection, query, where, getDocs, addDoc } from "./firebase-firestore.js";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
// Your web app's Firebase configuration
const firebaseConfig = {
apiKey: "XXXXXXXXXXXXXXX",
authDomain: "XXXXXX.firebaseapp.com",
projectId: "XXXXXX",
storageBucket: "XXXXXXX.appspot.com",
messagingSenderId: "XXXXXXXX",
appId: "1:XXXXXXXXXX:web:XXXXXXXXXXXXX"
};
const firebase_app = !getApps().length ? initializeApp(firebaseConfig) : getApp();
const db = getFirestore(firebase_app);
async function get_database_elements(db_name){
const q = query(collection(db, db_name));
const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
console.log(doc.id, " => ", doc.data());
});
}
//In order to use firebase_app and db inside the injected website
//pass to global scope is needed, because in module it has local scope
globalThis.firebase_app = firebase_app;
globalThis.db = db;
globalThis.get_database_elements = get_database_elements;
//This will inject the firebase module loader script.
function injectModule(file, node) {
var th = document.getElementsByTagName(node)[0];
var s = document.createElement('script');
s.setAttribute('type', 'module');
s.setAttribute('src', file);
th.appendChild(s);
}
injectModule(chrome.runtime.getURL('js/firebase/firebase_config.js'), 'body');
{
"name": "Example",
"version": "1.0.0",
"manifest_version": 3,
"description": "Example.",
"externally_connectable": {
"matches": [ "https://example.com/*" ]
},
"default_locale": "en",
"content_scripts": [
{
"matches": [
"https://example.com/*"
],
"js": [
"inject.js"
],
"run_at": "document_idle",
"all_frames": true
}
],
"web_accessible_resources": [
{
"resources":[
"js/firebase/firebase_config.js",
"js/firebase/firebase-app.js",
"js/firebase/firebase-firestore.js",
"js/firebase/firebase-database.js"
],
"matches": [ "https://example.com/*" ]
}
]
}
@cheadrian
Copy link
Author

cheadrian commented Feb 12, 2024

"Modify all firebase JS files to ensure all imports are from extension package, as remote script inserting is not allowed anymore in Manifest V3." In your case, it is ALLOWED. It is NOT allowed in the service worker. Inject inserts a tag script and it works quite well with remote scripts and without local ones (firbase-app, etc).

function injectScript(file, node) {
    var th = document.getElementsByTagName(node)[0];
    var s = document.createElement('script');
    s.setAttribute('type', 'text/javascript');
    s.setAttribute('src', file);
    th.appendChild(s);
}
injectScript('https://www.gstatic.com/firebasejs/10.8.0/firebase-app.js', 'head');
Refused to load the script 'https://www.gstatic.com/firebasejs/10.8.0/firebase-app.js' because it violates the following Content Security Policy directive: "script-src 'self' 'wasm-unsafe-eval' 'inline-speculation-rules' http://localhost:* http://127.0.0.1:*". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.

Extension Pages Policy

The extension_pages policy cannot be relaxed beyond this minimum value.

You can relax these directives on the sandbox space, but this would require to implement the message API, like @bhdrozgn .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment