Как использовать базу данных firebase в chrome extension

Я хочу использовать его как часть моего сценария контента, чтобы я мог получать данные из базы данных firebase. Тем не менее, я не знаю, как я могу ссылаться на скрипт, указанный в документах firebase:

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

Я знаю, что если бы я делал все это во всплывающей html-странице, тогда я мог бы загрузить тег сценария, но в скрипте содержимого нет html-страницы, кроме страницы содержимого, поэтому я не уверен, что это даже возможный.

Ответ 1

Добавление следующего в ваш файл манифеста расширений должно помочь:

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

Как только вы это сделаете, вы сможете получить доступ к API с помощью любого обычного клиента XHR из javascript вашего расширения (будьте осторожны с любыми проблемами безопасности).

Ответ 2

ContentScript запускается на странице DOM, но в другой изолированной программной среде JS, поэтому вы не можете напрямую внедрить JS через DOM, как показано в примере.

Я бы порекомендовал вам загрузить Firebase lib на фоновую страницу, а затем вы можете получить к нему доступ из фонового скрипта и прокси-запросов из вашего скрипта контента через фоновый бэкэнд. Это не приведет к загрузке firebase lib каждый раз, когда вы загружаете страницу, загружает скрипты содержимого, и она будет загружена один раз при инициализации фоновой страницы (или вы можете загрузить ее по запросу, используя непостоянный фоновый скрипт).

Пример:

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)
});

Другой вариант - загрузить вашу JS-библиотеку Firebase и код, который вам нужно запустить, в песочницу JS страницы, вставив ее в DOM страницы с помощью чего-то вроде:

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 JS sandbox and page DOM
var fn = function injectedFunction(seed) { /* your JS code you want to run is page sandbox */ }
var ele = document.createElement("script");
ele.textContent = fn+"console.log(injectedFunction());";

Но этот вариант очень плох, потому что CSP страницы может блокировать ваш JS в этом случае. document.body.appendChild(Ele);