Firebase模拟器但实际存储

huangapple go评论54阅读模式
英文:

Firebase Emulator but live storage

问题

当我使用存储模拟器时,我一直在努力将下载链接连接到第三方可以访问的链接 - 图像和视频优化工具。Firebase Storage 生产环境的 URL 是 https://firebasestorage.googleapis.com/...(可以在网络上访问),而本地环境的 URL 是 http://localhost:9199/...(无法访问)。

我尝试了很多方法来使 URL 可访问。我最终创建了另一个存储桶在我的生产环境上,然后身份验证、函数、Firestore 和托管都在本地模拟器上。

这样做可以工作,但我想知道这样做有什么风险?

有更好的方法吗?

编辑:根据评论添加我的 JSON 文件。

{
  "firestore": {
    "rules": "firestore.rules",
    "indexes": "firestore.indexes.json"
  },
  "functions": [
    {
      "source": "functions",
      "codebase": "default",
      "ignore": [
        "node_modules",
        ".git",
        "firebase-debug.log",
        "firebase-debug.*.log"
      ],
      "predeploy": [
        "npm --prefix \"$RESOURCE_DIR\" run lint"
      ]
    }
  ],
  "hosting": {
    "public": "build",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  },
  "storage": {
    "rules": "storage.rules"
  },
  "emulators": {
    "auth": {
      "port": 9099
    },
    "firestore": {
      "port": 8080
    },
    "hosting": {
      "port": 5000
    },
    "storage": {
      "port": 9199
    },
    "ui": {
      "enabled": true,
      "port": 4000
    },
    "singleProjectMode": true,
    "functions": {
      "port": 5001
    }
  }
}
英文:

When i use storage emulator, I have been struggling to connect download URLs to URLs that can be accessed by 3rd parties - image and video optimisation tools. Firebase Storage production url is https://firebasestorage.googleapis.com/...(accessible over the web) whereas local environment url is http://localhost:9199/...(inaccessible).

I tried a bunch of things make the URL accessible. I've resorted to creating another bucket on my production environment and then the auth, function, firestore and hosting is on the local emulator.

This works but i wonder, what are the risks to this?

Is there a better way?

Edit: Adding my json file as per comment.

{
  "firestore": {
    "rules": "firestore.rules",
    "indexes": "firestore.indexes.json"
  },
  "functions": [
    {
      "source": "functions",
      "codebase": "default",
      "ignore": [
        "node_modules",
        ".git",
        "firebase-debug.log",
        "firebase-debug.*.log"
      ],
      "predeploy": [
        "npm --prefix \"$RESOURCE_DIR\" run lint"
      ]
    }
  ],
  "hosting": {
    "public": "build",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  },
  "storage": {
    "rules": "storage.rules"
  },
  "emulators": {
    "auth": {
      "port": 9099
    },
    "firestore": {
      "port": 8080
    },
    "hosting": {
      "port": 5000
    },
    "storage": {
      "port": 9199
    },
    "ui": {
      "enabled": true,
      "port": 4000
    },
    "singleProjectMode": true,
    "functions": {
      "port": 5001
    }
  }
}

答案1

得分: 0

我认为您正在从节点环境而不是浏览器环境访问Firebase模拟器,因为只有在浏览器中运行时才能使用主机名,而在这里location.hostname也不起作用。

如果您在不检查''localhost''条件的情况下初始化,应该会获得结果。因为如果您在这里使用了typescript,您可能已经在主机名上收到了错误,例如

This comparison appears to be unintentional because the types '() => string' and 'string' have no overlap.
if(hostname === "localhost")
    🤬;

与其像您所做的那样从客户端初始化Firebase模拟器,我建议您使用一些env文件,并添加一个名为NODE_ENV = 'development'的变量,并基于该条件进行初始化,如下所示:

if(process.env.NODE_ENV === 'development') {
    connectAuthEmulator(auth, "http://localhost:9099");
    connectFirestoreEmulator(db, "localhost", 8080);
    connectDatabaseEmulator(database, "localhost", 9000);
    connectStorageEmulator(storage, "localhost", 9199);
    connectFunctionsEmulator(functions, "localhost", 5001);
}

或者只需在您的Firebase初始化文件中使用一个变量,如const useEmulator: boolean = true;,并根据该值进行检查,当您想连接到生产Firebase实例时,只需将useEmulator的值设置为false。

更新
让我们仔细检查您是否已经按照这些步骤操作,如果是的话,请再试一次。

  1. 使用 npm init -y 创建一个 node 项目,并按照这里所示配置typescript项目。
  2. 运行 firebase init,选择现有项目,并向CLI提供project_id,然后选择要在此情况下使用的功能,选择 Storage: Configure a security rules file for Cloud StorageEmulators: Set up local emulators for Firebase products 然后按回车键。
  3. 在firebase cli要求选择哪个模拟器时选择Storage模拟器。按Enter键。你将获得一个提示 Would you like to download the emulators now?(Y/n),输入Y然后按Enter。模拟器将被下载。
  4. 运行 npm install firebase 向您的项目添加firebase依赖项。
  5. 接下来创建src文件夹,创建firebase.ts文件,然后按如下方式添加您的firebase凭据:
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { connectAuthEmulator, getAuth } from "firebase/auth";
import { connectDatabaseEmulator, getDatabase } from "firebase/database";
import { connectFirestoreEmulator, getFirestore } from "firebase/firestore";
import { connectFunctionsEmulator, getFunctions } from "firebase/functions";
import { connectStorageEmulator, getStorage } from "firebase/storage";

const firebaseConfig = {  };

const useEmulator: boolean = true;

// Initialize Firebase Services
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const db = getFirestore(app);
const database = getDatabase(app);
const storage = getStorage(app);
const functions = getFunctions(app);

if(useEmulator) {
    connectAuthEmulator(auth, "http://localhost:9099");
    connectFirestoreEmulator(db, "localhost", 8080);
    connectDatabaseEmulator(database, "localhost", 9000);
    connectStorageEmulator(storage, "localhost", 9199);
    connectFunctionsEmulator(functions, "localhost", 5001);
} else console.log("If Block has been Skipped");
export { auth, db, database, storage, functions }
  1. 运行 firebase emulators:start 启动模拟器,它将输出UI URL和配置的模拟器服务URL。转到UI URL并将图像上传到存储模拟器。您将获得该图像的URL,例如:http://127.0.0.1:9199/v0/b/<project_id>.appspot.com/...
  2. 这将确保您的配置是正确的,如果有任何问题都不是来自firebase方面,那么您可以联系firebase支持。

参考:使应用程序连接到模拟器

英文:

I think you are accessing firebase emulator from the node environment and not in the browser environment as hostname will only work if the environment is running in the browser and here location.hostname will also not work.

If you initialize without checking the condition for ''localhost'' you should get the results. Because if you have used typescript here you might have got error on hostname like

This comparison appears to be unintentional because the types &#39;() =&gt; string&#39; and &#39;string&#39; have no overlap.
if(hostname === &quot;localhost&quot;)
    &#128070;

Instead of initializing the firebase emulators from the client like you did, I recommend you to use some env file and add one variable called NODE_ENV = ''development'' and initialize based on that condition as follows:

if(process.env.NODE_ENV === &#39;development&#39;) {
    connectAuthEmulator(auth, &quot;http://localhost:9099&quot;);
    connectFirestoreEmulator(db, &quot;localhost&quot;, 8080);
    connectDatabaseEmulator(database, &quot;localhost&quot;, 9000);
    connectStorageEmulator(storage, &quot;localhost&quot;, 9199);
    connectFunctionsEmulator(functions, &quot;localhost&quot;, 5001);
}

OR just use a variable like const useEmulator: boolean = true; in your firebase initialization file and check against this value and when you want to connect to production firebase instance just make the value of useEmulator to false.

Update :
Let's double check if you have followed these steps or not, if yes then try to give it a chance again.

  1. Create 1 node-project using npm init -y and configure typescript project as shown in here.
  2. Run firebase init and select existing project and provide project_id to the cli then select which features you want to use in this case select Storage: Configure a security rules file for Cloud Storage and Emulators: Set up local emulators for Firebase products then hit enter.
  3. Choose Storage emulator when firebase cli will ask for which emulators to choose. Hit Enter. You will get Would you like to download the emulators now?(Y/n) as a prompt, type Y then enter. Your emulators will get downloaded.
  4. Run npm install firebase to add firebase dependency to your project.
  5. Next create src folder and create firebase.ts file then add your firebase credentials as follows:
// Import the functions you need from the SDKs you need
import { initializeApp } from &quot;firebase/app&quot;;
import { connectAuthEmulator, getAuth } from &quot;firebase/auth&quot;;
import { connectDatabaseEmulator, getDatabase } from &quot;firebase/database&quot;;
import { connectFirestoreEmulator, getFirestore } from &quot;firebase/firestore&quot;;
import { connectFunctionsEmulator, getFunctions } from &quot;firebase/functions&quot;;
import { connectStorageEmulator, getStorage } from &quot;firebase/storage&quot;;

const firebaseConfig = {  };

const useEmulator: boolean = true;

// Initialize Firebase Services
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const db = getFirestore(app);
const database = getDatabase(app);
const storage = getStorage(app);
const functions = getFunctions(app);

if(useEmulator) {
    connectAuthEmulator(auth, &quot;http://localhost:9099&quot;);
    connectFirestoreEmulator(db, &quot;localhost&quot;, 8080);
    connectDatabaseEmulator(database, &quot;localhost&quot;, 9000);
    connectStorageEmulator(storage, &quot;localhost&quot;, 9199);
    connectFunctionsEmulator(functions, &quot;localhost&quot;, 5001);
} else console.log(&quot;If Block has been Skipped&quot;);
export { auth, db, database, storage, functions }
  1. Run firebase emulators:start to start the emulator it will spit out ui URL and configured emulator services urls. Go to the ui URL and upload an image to the storage emulator. You will get the url for that image like this : http://127.0.0.1:9199/v0/b/&lt;project_id&gt;.appspot.com/...
  2. This will ensure that your configuration is correct and there are no issues from the firebase side if any occurred then you can contact firebase support.

Reference : Instrument your app to talk to the emulators

huangapple
  • 本文由 发表于 2023年4月13日 21:58:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76006325.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定