How to use firebase database in chrome extension

ContentScript runs on page's DOM, but on different JS sandbox, so you can't directly inject JS via DOM as it is shown in the example.

I would recommend you to load firebase lib to the background page and then you can access it from your background script and proxy requests from your Content Script via background backend. This will not cause firebase lib loaded every time you load page loads content scripts and it will be load once on background page init (or you can load it by request using non-persistent background script).

Example:

manifest.json

{
    "manifest_version": 2,
    "name": "FireBase Demo",
    "description": "FireBase client demo",    
    "version": "0.0.1",
    "permissions": [
        "<all_urls>",
        "tabs"
    ],
     "background": {
       "page": "bg.html",
       "persistent": false
     },
     "content_scripts": [{
        "matches": ["https://*/*","http://*/*"],
        "js": ["cs.js"]
    }],
     "content_security_policy": "script-src 'self' https://www.gstatic.com/firebasejs/5.3.0/firebase.js; object-src 'self'"
}

bg.html

<html>
    <head>
        <script src="https://www.gstatic.com/firebasejs/5.3.0/firebase.js"></script>
        <script src="bg.js"></script>
    </head>
    <body></body>
</html>

bg.js

firebase.initializeApp({
  apiKey: '...',
  authDomain: '...',
  projectId: '...'
});

var db = firebase.firestore();
db.settings({timestampsInSnapshots: true});
  chrome.runtime.onMessage.addListener((msg, sender, response) => {
    if (msg.command == "add"){
      console.log("process msg add", msg, sender, response);
      db.collection(msg.collection).add(msg.data).then((result) => {
        console.log("success", result)
        response({type: "result", status: "success", data: result, request: msg});
      }).catch((result) => {
        console.log("error", result);
        response({type: "result", status: "error", data: result, request: msg}); 
      });
    }
    return true;
  });

cs.js

chrome.runtime.sendMessage({command: "add", collection: "users", data: {name: "user"}}, (msg) => {
  console.log("response", msg)
});

Another variant is to load your firebase JS lib and the code you need to run to the page's JS sandbox by injecting it to the page's DOM with something like:

var script = document.createElement("script");
script.src = "https://www.gstatic.com/firebasejs/5.3.0/firebase.js"
document.body.append(script); // firebase lib will be loaded to the page's JS sandbox and page's DOM
var fn = function injectedFunction(seed) { /* your JS code you want to run is page's sandbox */ }
var ele = document.createElement("script");
ele.textContent = fn+"console.log(injectedFunction());";

But this variant is very bad, because page's CSP may block your JS in this case. document.body.appendChild(ele);


Adding the following to your extensions manifest file should do the trick:

"permissions": [
    "https://www.gstatic.com/firebasejs/5.3.0/firebase.js"
],

Once you've done that you should be able to access the API using any normal XHR client from your extensions javascript (be careful for any security concerns).