Firebase托管与动态云功能重写 [英] Firebase Hosting with dynamic cloud functions rewrites

查看:164
本文介绍了Firebase托管与动态云功能重写的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为 api 的函数,在firebase中有一个基于express.js的云功能应用程序。要使用自定义域名,我尝试使用Firebase Hosting重写来将特定网址路由到该功能。
我正在关注有关云端功能和Firebase托管的官方文档, https:/ /firebase.google.com/docs/hosting/functions ,并尝试了许多组合,包括以下内容:

  重写:[
{
source:/ api / **,
function:api
}
]

重写:[
{
source:/ api /:path1 /:dat1 / dat,
function:api /:path1 / :dat1 / dat

]
rewrites:[
{
source:/ api / path1 / dat1 / dat,
function:api
}
]
rewrites:[
{
source:/ api / * / * / * ,
function:api
}
]



<不幸的是,似乎没有任何可能的组合。
我的快车应用程序有以下的GET路径,我计​​划使用:

pre $ user $:userId / :userData'
'/ api / users /:userId /:userData / json'
'/ api / users /:userId /'

以及其他与这些类似的内容。在我的请求中的:userId和:userData是params,因为它与express.js一起工作



所需函数按照预期在
中工作

  https://my-firebase-app.cloudfunctions.net 

但它们不能与

  https://my-app.firebaseapp.com 

请告诉我这些应该如何工作,以及我做错了什么。

b
$ b

编辑:
下面是我的云功能导出的示例:

  const functions = require('firebase-functions'); 
const express = require('express');
const app = express();
$ b app.get('/ users /:userId /:userData / json',(req,res)=> {
//在这里做的应用程序
}
//更多的app.get格式相同

exports.api = functions.https.onRequest(app);
@ DougStevenson的建议后,我尝试了以下配置:

我试过以下在我的firebase.json中,

  {
hosting:{
rewrites:[
{
source:/ api,
function:api
}
],
public:public
}
}

但是我得到同样的问题,从来没有调用
我读了如何重写是最后的手段选项,如果有文件存在于主机,它不会去指定的功能(我试图寻找这个ws提到的SO帖子,但我找不到)所以我从主机的p中删除了404.html和index.html文件ublic目录,因为我不需要它们。但问题依然存在。编辑2:
好​​吧,经过大量的试验和错误之后,我只好用以下格式对路径进行硬编码:

 重写:[
{
source:/ users / ** / ** / json,
function:api
},
{
source:/ api / users / ** / ** / json,
函数:api
}
]

在此之后,快速应用配置如下所示:

$ $ p $ $ $ c $ app.get('/ users /:userId /:userData / json',Foo)



我还是希望有人能够提出一个更好的方法来完成这个任务,而不是手动把每个必需的Uri在主机重写。

解决方案

这个主要的问题似乎是这样的:

  {
source:/ api,
function:api
}

实际上是重写为 https://my-firebase-app.cloudfunctions.net/api/api 而不是 https://my-firebase-app.cloudfunctions.net/api 就像你所期望的一样。注意如何重复 api



我的解决方案是创建一个 main 函数,其中包含所有其他顶级函数:

$ $ $ $ codeonst函数require('firebase-functions' );
const express = require('express');
const app = express();
$ b app.get('/ users /:userId /:userData / json',(req,res)=> {
//在这里做的应用程序
}
//以相同的格式添加更多的app.get

//创建main函数来托管所有其他顶层函数
const main = express();
main.use('/ api',app);

exports.main = functions.https.onRequest(main);
main 函数委托给所有其他函数,而不会破坏你的URL结构:


>

  {
source:/ api / **,//**确保包含路径/ api / users /:userId
function:main
}


$ b $现在你可以通过 https://my-app.firebaseapp.com/api/users访问所有的 api 函数调用/:userId /:userData 就像你期望的一样。



调用这个端点现在重写为 https: //my-firebase-app.cloudfunctions.net/main/api 这是技术上是正确的。您可以添加更多的顶级函数,只要将它们添加到 main 函数即可:

  const hooks = express(); 
main.use('/ hooks /,hooks);


I have an express.js based cloud functions app on firebase in a function named api. To use a custom domain, I'm trying to use Firebase Hosting rewrites to route the specific URL to the function. I'm following the official documentation about cloud functions and Firebase hosting here, https://firebase.google.com/docs/hosting/functions, and have tried many combinations including the following:

"rewrites": [
      {
        "source": "/api/**",
        "function": "api"
      }
    ]

"rewrites": [
      {
        "source": "/api/:path1/:dat1/dat",
        "function": "api/:path1/:dat1/dat"
      }
    ]
"rewrites": [
      {
        "source": "/api/path1/dat1/dat",
        "function": "api"
      }
    ]
"rewrites": [
      {
        "source": "/api/*/*/*",
        "function": "api"
      }
    ]

Sadly, It doesn't seem to work for any possible combination. My express app has the following GET paths I plan on using:

'/api/users/:userId/:userData'
'/api/users/:userId/:userData/json'
'/api/users/:userId/'

and others similar to these. the :userId and :userData are the params in my request, as it works with express.js

The required functions work as expected in

https://my-firebase-app.cloudfunctions.net

but they do not work with

https://my-app.firebaseapp.com

Please tell me how these are supposed to work and what I'm doing wrong.

EDIT: Here is a sample of what my cloud functions export looks like

const functions = require('firebase-functions');
const express = require('express');
const app = express();

app.get('/users/:userId/:userData/json', (req, res) => {
    // Do App stuff here
}
// A couple more app.get in the same format

exports.api = functions.https.onRequest(app);

EDIT 2: After @DougStevenson's suggestion, I tried the following configuration

I tried the following in my firebase.json ,

{
  "hosting": {
    "rewrites": [
      {
        "source": "/api",
        "function": "api"
      }
    ],
    "public": "public"
  }
}

But I got the same problem, the function is never called. I read about how the rewrites are last resort options and if there are files present in the hosting, it will not go to the specified function.(I tried looking for the SO post where this ws mentioned but I can't find it) So I removed the 404.html and index.html files from hosting's public directory, since I don't need them anyway. But the problem still remained.

EDIT 2: Okay, so after a lot of trial and error, I just had to hard code the paths in the following format:

rewrites : [
      {
        "source": "/users/**/**/json",
        "function": "api"
      },
      {
        "source": "/api/users/**/**/json",
        "function": "api"
      }
]

After this, the express app is configured something like this:

app.get('/users/:userId/:userData/json', Foo)

I still would prefer if someone could suggest a better way to accomplish this rather than manually putting in each required Uri in the hosting rewrites.

解决方案

What seems to be the main issue is that this:

{
    "source": "/api",
    "function": "api"
}

is actually rewriting to https://my-firebase-app.cloudfunctions.net/api/api instead of https://my-firebase-app.cloudfunctions.net/api like you'd expect. Notice how api is repeated.

My solution to this is to create a main function which hosts all other top-level functions:

const functions = require('firebase-functions');
const express = require('express');
const app = express();

app.get('/users/:userId/:userData/json', (req, res) => {
    // Do App stuff here
}
// A couple more app.get in the same format

// Create "main" function to host all other top-level functions
const main = express();
main.use('/api', app);

exports.main = functions.https.onRequest(main);

You can now use this main function to delegate to all other functions without breaking your URL structure:

{
    "source": "/api/**", // "**" ensures we include paths such as "/api/users/:userId"
    "function": "main"
}

And voila! You can now access all api function calls via https://my-app.firebaseapp.com/api/users/:userId/:userData just like you'd expect.

Calling this endpoint, now rewrites to https://my-firebase-app.cloudfunctions.net/main/api which is technically correct. You can then add more top-level functions by simply adding them to your main function if you wish:

const hooks = express();
main.use('/hooks/, hooks);

这篇关于Firebase托管与动态云功能重写的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆