J'ai une application de fonctions cloud basée sur express.js sur firebase dans une fonction nommée api
. Pour utiliser un domaine personnalisé, j'essaie d'utiliser les réécritures de Firebase Hosting pour router l'URL spécifique vers la fonction. Je suis ici la documentation officielle sur les fonctions cloud et l'hébergement Firebase, https://firebase.google.com/docs/hosting/functions , et j'ai essayé de nombreuses combinaisons, y compris les suivantes:
"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"
}
]
Malheureusement, cela ne semble pas fonctionner pour une combinaison possible. Mon application express a les chemins GET suivants que je prévois d'utiliser:
'/api/users/:userId/:userData'
'/api/users/:userId/:userData/json'
'/api/users/:userId/'
et d'autres similaires à ceux-ci. les: userId et: userData sont les paramètres de ma demande, car cela fonctionne avec express.js
Les fonctions requises fonctionnent comme prévu dans
https://my-firebase-app.cloudfunctions.net
mais ils ne fonctionnent pas avec
https://my-app.firebaseapp.com
Veuillez me dire comment ceux-ci sont censés fonctionner et ce que je fais mal.
EDIT: Voici un exemple de ce à quoi ressemble l'export de mes fonctions cloud
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: Après la suggestion de @ DougStevenson, j'ai essayé la configuration suivante
J'ai essayé ce qui suit dans mon firebase.json,
{
"hosting": {
"rewrites": [
{
"source": "/api",
"function": "api"
}
],
"public": "public"
}
}
Mais j'ai le même problème, la fonction n'est jamais appelée. J'ai lu comment les réécritures sont des options de dernier recours et s'il y a des fichiers présents dans l'hébergement, il n'ira pas à la fonction spécifiée. (J'ai essayé de chercher le SO poste où cela a été mentionné) mais je ne le trouve pas) J'ai donc supprimé les fichiers 404.html et index.html du répertoire public de l'hébergement, car je n'en ai pas besoin de toute façon. Mais le problème restait.
EDIT 2: D'accord, donc après beaucoup d'essais et d'erreurs, je n'ai eu qu'à coder en dur les chemins dans le format suivant:
rewrites : [
{
"source": "/users/**/**/json",
"function": "api"
},
{
"source": "/api/users/**/**/json",
"function": "api"
}
]
Après cela, l'application express est configurée quelque chose comme ceci:
app.get('/users/:userId/:userData/json', Foo)
Je préférerais toujours que quelqu'un suggère une meilleure façon d'accomplir cela plutôt que de mettre manuellement chaque Uri requis dans les réécritures d'hébergement.
Ce qui semble être le principal problème est que ceci:
{
"source": "/api",
"function": "api"
}
est en train de réécrire dans https://my-firebase-app.cloudfunctions.net/api/api
au lieu de https://my-firebase-app.cloudfunctions.net/api
comme vous vous y attendez. Remarquez comment api
est répété.
Ma solution est de créer une fonction main
qui héberge toutes les autres fonctions de niveau supérieur:
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);
Vous pouvez maintenant utiliser cette fonction main
pour déléguer à toutes les autres fonctions sans casser votre structure d'URL:
{
"source": "/api/**", // "**" ensures we include paths such as "/api/users/:userId"
"function": "main"
}
Et le tour est joué! Vous pouvez désormais accéder à tous les appels de fonction api
via https://my-app.firebaseapp.com/api/users/:userId/:userData
comme vous vous en doutez.
L'appel de ce point de terminaison est désormais réécrit en https://my-firebase-app.cloudfunctions.net/main/api
ce qui est techniquement correct. Vous pouvez ensuite ajouter d'autres fonctions de niveau supérieur en les ajoutant simplement à votre fonction main
si vous le souhaitez:
const hooks = express();
main.use('/hooks/, hooks);
Vous pouvez utiliser une seule règle de réécriture d'hébergement Firebase avec un middleware de réécriture complémentaire dans Express.
Ajoutez un réécriture dans votre firebase.json
fichier.
{
"source": "/api/**",
"function": "api"
}
Incluez un middleware app.use () pour réécrire l'url de la requête.
const functions = require('firebase-functions');
const express = require('express');
const API_PREFIX = 'api';
const app = express();
// Rewrite Firebase hosting requests: /api/:path => /:path
app.use((req, res, next) => {
if (req.url.indexOf(`/${API_PREFIX}/`) === 0) {
req.url = req.url.substring(API_PREFIX.length + 1);
}
next();
});
app.get('/users/:userId/:userData/json', (req, res) => {
// Do App stuff here
});
exports[API_PREFIX] = functions.https.onRequest(app);