如何将所有服务器请求重定向到Firebase Hosting中的功能

Ric*_*d G 3 javascript firebase firebase-hosting google-cloud-functions

试图用Firebase实现SSR,所以我正在使用一个函数来预渲染React App的每个页面。除主页外,它运行良好,因此必须是Firebase重定向上的匹配错误或快速路由本身上的匹配错误。

firebase.json

{
  "firestore": {
    "rules": "firestore.rules",
    "indexes": "firestore.indexes.json"
  },
  "functions": {
    "predeploy": [
      "npm --prefix \"$RESOURCE_DIR\" run lint"
    ]
  },
  "hosting": {
    "public": "build",
    "rewrites": [
      {
        "source": "**",
        "function": "contentServer"
      }
    ],
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

contentServer.js

import * as functions from 'firebase-functions';
import * as fs from 'fs';
import * as path from 'path';

import React from 'react';
import Helmet from 'react-helmet';
import { renderToString } from 'react-dom/server';
import Server from '../browser/Server.js';

const express = require('express');

const app = express();

// might be this? Also tried /**

app.get(['**'], (request, response) => {
  const context = {};
  const location = request.url;
  console.log('Processing request for ', location);

  let appCode;
  try {
    appCode = renderToString(<Server context={context} location={location} />);
  } catch (err) {
    appCode = 'with error';
  }

  // const appState = {
  //   pageTitle: 'Hello World',
  // };

  // const preloadedState = JSON.stringify(appState).replace(/</g, '\\u003c');
  const fileName = path.join(__dirname, '../index.html');
  const htmlTemplate = fs.readFileSync(fileName, 'utf8');
  const head = Helmet.renderStatic();

  const responseString = htmlTemplate
    .replace('<div id="root"></div>', `<div id="root">${appCode}</div>`)
    .replace('<title>React App</title>', `${head.title}\n${head.link}`);
  return response.send(responseString);
});

export default functions.https.onRequest(app);
Run Code Online (Sandbox Code Playgroud)

卷曲

我跑 firebase serve --only functions,hosting

然后使用curl检查响应:

curl http://localhost:5000 - does not render the home page - just the standard react page
curl http://localhost:5000/ - also does not work - just the standard react page.
curl http://localhost:5000/contact-us - works well and returns the contact us page, all other pages on the site work and trigger the function.
Run Code Online (Sandbox Code Playgroud)

Dou*_*son 5

如果要将每个单个URL重定向到您的主机到Cloud Functions中的快速应用程序,则需要执行以下操作:

确保您的公共托管文件夹中没有index.html(否则它将始终与path一起提供/)。

在firebase.json中配置Firebase托管,以将所有url重写为一个函数(您目前正在“托管”块中这样做,这很好):

"rewrites": [
  {
    "source": "**",
    "function": "contentServer"
  }
]
Run Code Online (Sandbox Code Playgroud)

编写一个与重写中的函数同名导出的Cloud Function ,并附加一个处理用通配符路由的Express应用*。至少在functions文件夹的index.js中:

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

const app = express()

app.get("*", (request, response) => {
    response.send("OK")
})

exports.contentServer = functions.https.onRequest(app)
Run Code Online (Sandbox Code Playgroud)

如果使用本地运行此命令firebase serve --only hosting,functions,则发送到localhost:5000的每个路径都将显示“ OK”。