typescript - Jak používat emulátory Firebase Pub/Sub k lokálnímu testování časovaných funkcí?
Používám Firebase pro projekt a pracuji na vytváření funkce plánování pomocí následujícího kódu. Chci zaznamenávat zprávu každou minutu, kdy se toto spustí.
export const timedQuery = functions.pubsub.schedule('1 * * * *').onRun((context) => {
console.log("I am running")
return null;
})
Hlavní logika kódu mi funguje pod HTTP funkcí a rád bych zjistil, zda to funguje lokálně před nasazením do produkce. Procházením dokumentace Firebase jsem si stáhl všechny emulátory Firebase a používám „firebase emulators:start“, aby se spustily. Z logů to vypadá, že můj emulátor Pub/Sub se spustí úspěšně na localhost:8085 a funkce Pub/Sub je inicializována, nicméně ani po čekání 2-3 minut se nic nevypíše. Je možné testovat naplánované funkce lokálně?
Také jsem to vytvořil, aniž bych použil plánovač Google Cloud, protože jsem pouze na Firebase.
Odpověď č. 1
Obcházení
Emulátor PubSub stále nepodporuje plánované funkce.
Ale můžete použít firebase functions:shell a setInterval k simulaci plánovače.
POZNÁMKA: Ujistěte se, že spouštíte emulator Firebase lokálně, jinak může shell volat funkce v Produkci !!
firebase functions:shell
firebase > setInterval(() => yourScheduledFunc(), 60000)
Nevycházejte, pak se vaše funkce bude spouštět každých 60 sekund.
POZNÁMKA: funkce spuštěné v shellu se nezobrazí v protokolu emulátoru.
Odpověď č. 2
Místní emulátor Firebase v současné době nenasimuluje skutečné plánované funkce. Dokumentace uvádí:
Firebase CLI obsahuje emulátor Cloud Functions, který dokáže emulovat následující typy funkcí:
- Funkce HTTPS
- Volatelné funkce
- Funkce Cloud Firestore
Navrhuji podat žádost o funkci podpora Firebase.
Když nasazujete plánovanou funkci, ve skutečnosti používáte Google Cloud Scheduler na pozadí. Detaily jsou spravovány za vás. Jak je uvedeno v dokumentaci:
Pokud chcete naplánovat spouštění funkcí v určených časech, použijte functions.pubsub.schedule().onRun() Tato pohodlná metoda vytvoří téma Google Cloud Pub/Sub a použije Google Cloud Scheduler k spouštění událostí na tomto tématu, čímž zajistí, že vaše funkce poběží podle požadovaného harmonogramu.
Navrhuji přepracovat kód vaší funkce do metody, kterou můžete testovat přímým voláním pomocí testovacího rámce dle vašeho výběru. Také ji můžete dočasně obalit do HTTP funkce a volat ji tímto způsobem.
Odpověď č. 3
Ve skutečnosti existuje emulator Firebase PubSub. Pro jeho povolení musíte mít nainstalovaný nejnovější CLI (je to určitě od verze 8.2.0).
- Znovu spusťte inicializaci Firebase
- Vyberte emulátory (mezerník)
- Vyberte PubSub (a další, které chcete)
- Konfigurujte požadované vývojové porty
- Nechte CLI nainstalovat emulátory
Vytvořte místně testovací skript pro odesílání zpráv PubSub do fronty:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const { PubSub } = require('@google-cloud/pubsub');
const pubsub = new PubSub();
exports.pubsubWriter = functions.https.onRequest(async (req, res) => {
console.log("Pubsub Emulator:", process.env.PUBSUB_EMULATOR_HOST);
const msg = await pubsub.topic('test-topic').publishJSON({
foo: 'bar',
date: new Date()
}, { attr1: 'value' });
res.json({
published: msg
})
});
Odpověď č. 4
Opětovné spuštění firebase init mi nefungovalo kvůli určitým důvodům.
Nakonec jsem ručně upravil soubor firebase.json,
Citace souvisejících dokumentů:
Změňte porty emulátoru spuštěním příkazu firebase init emulators nebo úpravou souboru firebase.json ručně.
// firebase.json
{
"hosting": {
// stuff...
},
"functions": {
// stuff...
},
"emulators": {
"functions": {
"port": 5001
},
"hosting": {
"port": 5000
},
"ui": {
"enabled": true
},
"firestore": {
"port": 8080
},
// * * * * * * * * *THIS👇 * * * * * * * * * * * * * * * * * * * * * * *
"pubsub": {
"port": "8085"
}
// * * * * * * * * *THIS👆 * * * * * * * * * * * * * * * * * * * * * * *
},
// more stuff...
}
