Bagaimana cara menyusun Fungsi Cloud untuk Firebase untuk menggunakan beberapa fungsi dari banyak file?

164

Saya ingin membuat beberapa Fungsi Cloud untuk Firebase dan menyebarkan semuanya sekaligus pada satu proyek. Saya juga ingin memisahkan setiap fungsi menjadi file yang terpisah. Saat ini saya dapat membuat beberapa fungsi jika saya menempatkan keduanya di index.js seperti:

exports.foo = functions.database.ref('/foo').onWrite(event => {
    ...
});

exports.bar = functions.database.ref('/bar').onWrite(event => {
    ...
});

Namun saya ingin meletakkan foo dan bar di file terpisah. Saya mencoba ini:

/functions
|--index.js (blank)
|--foo.js
|--bar.js
|--package.json

dimana foo.js berada

exports.foo = functions.database.ref('/foo').onWrite(event => {
    ...
});

dan bar.js adalah

exports.bar = functions.database.ref('/bar').onWrite(event => {
    ...
});

Apakah ada cara untuk mencapai ini tanpa meletakkan semua fungsi di index.js?

jasonirota
sumber
1
@ JPVentura. Benar-benar tidak mengerti kamu dengan baik. Tolong jelaskan.
HuyLe
Apakah ini telah diperbarui untuk v1.0? Saya mengalami masalah: stackoverflow.com/questions/50089807/…
tccpg288
2
FYI, contoh fungsi Firebase resmi ini berisi beberapa .jsfile yang diimpor melalui require: github.com/firebase/functions-samples/tree/master/…
xanderiel
Ini mungkin bermanfaat: stackoverflow.com/questions/43486278/…
Ramesh-X

Jawaban:

126

Ah, Cloud Functions untuk Firebase memuat modul simpul secara normal, jadi ini berfungsi

struktur:

/functions
|--index.js
|--foo.js
|--bar.js
|--package.json

index.js:

const functions = require('firebase-functions');
const fooModule = require('./foo');
const barModule = require('./bar');

exports.foo = functions.database.ref('/foo').onWrite(fooModule.handler);
exports.bar = functions.database.ref('/bar').onWrite(barModule.handler);

foo.js:

exports.handler = (event) => {
    ...
};

bar.js:

exports.handler = (event) => {
    ...
};
jasonirota
sumber
1
Bisakah saya misalnya memiliki beberapa fungsi dalam modul foo? Jika demikian, bagaimana sebaiknya menerapkannya?
Alexander Khitev
1
Saya kira Anda bisa, dan menetapkan penangan yang berbeda untuk berbagai fungsi yang diekspor dari foo: exports.bar = functions.database.ref ('/ foo'). OnWrite (fooModule.barHandler); exports.baz = functions.database.ref ('/ bar'). onWrite (fooModule.bazHandler);
jasonirota
44
Saya tidak suka solusi ini karena memindahkan informasi (yaitu jalur basis data) dari foo.js dan bar.js ke index.js yang jenisnya mengalahkan titik memiliki file-file terpisah.
bvs
Saya setuju dengan @bvs, saya pikir Ced memiliki pendekatan yang baik. Saya akan sedikit memodifikasinya dengan secara eksplisit mengekspor setiap modul untuk membuat index.ts super jelas mis. Ekspor {newUser} dari "./authenticationFunctions"
Alan
2
Saya pikir pertanyaan awal saya hanya tentang menyebarkan beberapa fungsi dengan 1 proyek tanpa meletakkan fungsi dalam file index.js, di mana dan bagaimana Anda menyampaikan informasi basis data tidak dalam ruang lingkup. Kalau saya, saya mungkin akan membuat modul terpisah yang mengontrol akses database dan memerlukannya di foo.js dan bar.js secara terpisah, tetapi itu adalah keputusan gaya.
jasonirota
75

Jawaban oleh @jasonirota sangat membantu. Tetapi mungkin bermanfaat untuk melihat kode yang lebih rinci, terutama dalam hal fungsi yang dipicu HTTP.

Menggunakan struktur yang sama seperti pada jawaban @ jasonirota, katakanlah Anda ingin memiliki dua fungsi pemicu HTTP terpisah dalam dua file berbeda:

struktur direktori:

    /functions
       |--index.js
       |--foo.js
       |--bar.js
       |--package.json`

index.js:

'use strict';
const fooFunction = require('./foo');
const barFunction = require('./bar');

// Note do below initialization tasks in index.js and
// NOT in child functions:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase); 
const database = admin.database();

// Pass database to child functions so they have access to it
exports.fooFunction = functions.https.onRequest((req, res) => {
    fooFunction.handler(req, res, database);
});
exports.barFunction = functions.https.onRequest((req, res) => {
    barFunction.handler(req, res, database);
});

foo.js:

 exports.handler = function(req, res, database) {
      // Use database to declare databaseRefs:
      usersRef = database.ref('users');
          ...
      res.send('foo ran successfully'); 
   }

bar.js:

exports.handler = function(req, res, database) {
  // Use database to declare databaseRefs:
  usersRef = database.ref('users');
      ...
  res.send('bar ran successfully'); 
}
Mahasiswa
sumber
Struktur saat ini di index.js tidak berfungsi dengan baik untuk saya. Apa yang harus saya lakukan adalah mengimpor modul firebase terlebih dahulu, kemudian menginisialisasi aplikasi dan kemudian mengimpor fungsi dari folder lain. Dengan begitu aplikasi saya pertama kali menginisialisasi, mengotentikasi, apa pun dan kemudian mengimpor fungsi-fungsi yang memerlukan aplikasi untuk diinisialisasi sebelumnya.
tonkatata
47

Pembaruan: Doc ini seharusnya membantu , jawaban saya lebih tua dari pada doc ini.


Inilah cara saya melakukannya secara pribadi dengan naskah:

/functions
   |--src
      |--index.ts
      |--http-functions.ts
      |--main.js
      |--db.ts
   |--package.json
   |--tsconfig.json

Izinkan saya mengawali ini dengan memberikan dua peringatan untuk membuat ini bekerja:

  1. urutan urusan impor / ekspor di index.ts
  2. db harus berupa file terpisah

Untuk poin nomor 2, saya tidak yakin mengapa. Secundo Anda harus menghormati konfigurasi indeks saya, utama dan db persis (setidaknya untuk mencobanya).

index.ts : berkaitan dengan ekspor. Saya merasa lebih bersih untuk membiarkan index.ts berurusan dengan ekspor.

// main must be before functions
export * from './main';
export * from "./http-functions";

main.ts : Berurusan dengan inisialisasi.

import { config } from 'firebase-functions';
import { initializeApp } from 'firebase-admin';

initializeApp(config().firebase);
export * from "firebase-functions";

db.ts : hanya mengekspor ulang db sehingga namanya lebih pendek daridatabase()

import { database } from "firebase-admin";

export const db = database();

http-functions.ts

// db must be imported like this
import { db } from './db';
// you can now import everything from index. 
import { https } from './index';  
// or (both work)
// import { https } from 'firebase-functions';

export let newComment = https.onRequest(createComment);

export async function createComment(req: any, res: any){
    db.ref('comments').push(req.body.comment);
    res.send(req.body.comment);
}
Ced
sumber
seperti apa tsconfig Anda? bagaimana saya bisa mengkompilasi ke folder dist dan membiarkan fungsi gcloud tahu di mana index.js saya? Apakah Anda memiliki kode di github? :)
bersling
@ choopage-JekBao maaf sudah lama, saya tidak punya proyek lagi. Jika saya ingat dengan benar, Anda dapat memberikan direktori konfigurasi firebase (yang publik secara default). Saya bisa saja salah karena sudah lebih dari setahun
Ced
Hey @ced - mengapa konten tidak bisa db.tsmasuk main.ts(setelah instantiasi admin?). Atau apakah Anda baru saja memisahkan diri dengan cara ini untuk kejelasan / kesederhanaan?
dsg38
1
@ dsg38 ini diposting terlalu lama, saya tidak benar-benar melihat mengapa itu harus di file terpisah melihat jawabannya sekarang .. Saya pikir itu untuk kejelasan
Ced
21

Dengan Node 8 LTS sekarang tersedia dengan Cloud / Firebase Functions, Anda dapat melakukan hal berikut dengan operator yang tersebar:

/package.json

"engines": {
  "node": "8"
},

/index.js

const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();

module.exports = {
  ...require("./lib/foo.js"),
  // ...require("./lib/bar.js") // add as many as you like
};

/lib/foo.js

const functions = require("firebase-functions");
const admin = require("firebase-admin");

exports.fooHandler = functions.database
  .ref("/food/{id}")
  .onCreate((snap, context) => {
    let id = context.params["id"];

    return admin
      .database()
      .ref(`/bar/${id}`)
      .set(true);
  });
Luke Pighetti
sumber
Saya bertanya-tanya apakah semakin banyak impor memperlambat awal yang dingin dari masing-masing fungsi atau apakah harus ada banyak modul yang terpisah sepenuhnya dikembangkan secara terpisah?
Simon Fakir
2
saya mendapatkan kesalahan parting eslint unexpected token ...di dalam index.js.
thomas
Mungkin Anda tidak menggunakan Node 8
Luke Pighetti
@SimonFakir pertanyaan bagus. Apakah Anda menemukan sesuatu tentang itu?
atereshkov
@atereshkov ya saya menemukan cara untuk hanya memuat fungsi yang diminta termasuk dependensinya menggunakan "process.env.FUNCTION_NAME" mirip dengan jawaban di bawah ini. Saya juga dapat membagikan repo saya sebagai referensi jika Anda dihubungi, hubungi saya.
Simon Fakir
15

Agar tetap sederhana (tetapi berfungsi), saya secara pribadi menyusun kode saya seperti ini.

Tata letak

├── /src/                      
   ├── index.ts               
   ├── foo.ts           
   ├── bar.ts
|   ├── db.ts           
└── package.json  

untuk

import * as functions from 'firebase-functions';
export const fooFunction = functions.database()......... {
    //do your function.
}

export const someOtherFunction = functions.database().......... {
    // do the thing.
}

bar.ts

import * as functions from 'firebase-functions';
export const barFunction = functions.database()......... {
    //do your function.
}

export const anotherFunction = functions.database().......... {
    // do the thing.
}

db.ts

import * as admin from 'firebase-admin';
import * as functions from 'firebase-functions';

export const firestore = admin.firestore();
export const realtimeDb = admin.database();

index.ts

import * as admin from 'firebase-admin';
import * as functions from 'firebase-functions';

admin.initializeApp(functions.config().firebase);
// above codes only needed if you use firebase admin

export * from './foo';
export * from './bar';

Berfungsi untuk direktori dari semua level bersarang. Cukup ikuti pola di dalam direktori juga.

kredit untuk jawaban @zaidfazil

Reza
sumber
1
Ini adalah salah satu jawaban paling sederhana untuk naskah, terima kasih. Bagaimana Anda mengatasi satu contoh database firebase misalnya? admin.initializeApp(functions.config().firestore) const db = admin.firestore();Di mana Anda meletakkan ini dan bagaimana Anda merujuknya di foo and bar?
elprl
Hei - mengapa konten tidak bisa db.tsmasuk index.ts(setelah instantiasi admin?). Atau apakah Anda baru saja memisahkan diri dengan cara ini untuk kejelasan / kesederhanaan?
dsg38
@ dsg38 Anda dapat menggabungkan semuanya, ini membuatnya jelas
Reza
10

Dalam hal Babel / Flow akan terlihat seperti ini:

Tata Letak Direktori

.
├── /build/                     # Compiled output for Node.js 6.x
├── /src/                       # Application source files
   ├── db.js                   # Cloud SQL client for Postgres
   ├── index.js                # Main export(s)
   ├── someFuncA.js            # Function A
   ├── someFuncA.test.js       # Function A unit tests
   ├── someFuncB.js            # Function B
   ├── someFuncB.test.js       # Function B unit tests
   └── store.js                # Firebase Firestore client
├── .babelrc                    # Babel configuration
├── firebase.json               # Firebase configuration
└── package.json                # List of project dependencies and NPM scripts


src/index.js - Ekspor utama

export * from './someFuncA.js';
export * from './someFuncB.js';


src/db.js - Cloud SQL Client untuk Postgres

import { Pool } from 'pg';
import { config } from 'firebase-functions';

export default new Pool({
  max: 1,
  user: '<username>',
  database: '<database>',
  password: config().db.password,
  host: `/cloudsql/${process.env.GCP_PROJECT}:<region>:<instance>`,
});


src/store.js - Firebase Firestore Client

import firebase from 'firebase-admin';
import { config } from 'firebase-functions';

firebase.initializeApp(config().firebase);

export default firebase.firestore();


src/someFuncA.js - Fungsi A

import { https } from 'firebase-functions';
import db from './db';

export const someFuncA = https.onRequest(async (req, res) => {
  const { rows: regions } = await db.query(`
    SELECT * FROM regions WHERE country_code = $1
  `, ['US']);
  res.send(regions);
});


src/someFuncB.js - Fungsi B

import { https } from 'firebase-functions';
import store from './store';

export const someFuncB = https.onRequest(async (req, res) => {
  const { docs: regions } = await store
    .collection('regions')
    .where('countryCode', '==', 'US')
    .get();
  res.send(regions);
});


.babelrc

{
  "presets": [["env", { "targets": { "node": "6.11" } }]],
}


firebase.json

{
  "functions": {
    "source": ".",
    "ignore": [
      "**/node_modules/**"
    ]
  }
}


package.json

{
  "name": "functions",
  "verson": "0.0.0",
  "private": true,
  "main": "build/index.js",
  "dependencies": {
    "firebase-admin": "^5.9.0",
    "firebase-functions": "^0.8.1",
    "pg": "^7.4.1"
  },
  "devDependencies": {
    "babel-cli": "^6.26.0",
    "babel-core": "^6.26.0",
    "babel-jest": "^22.2.2",
    "babel-preset-env": "^1.6.1",
    "jest": "^22.2.2"
  },
  "scripts": {
    "test": "jest --env=node",
    "predeploy": "rm -rf ./build && babel --out-dir ./build src",
    "deploy": "firebase deploy --only functions"
  }
}


$ yarn install                  # Install project dependencies
$ yarn test                     # Run unit tests
$ yarn deploy                   # Deploy to Firebase
Konstantin Tarkus
sumber
9

bigcodenerd.org menguraikan pola arsitektur yang lebih sederhana untuk memisahkan metode menjadi file yang berbeda dan diekspor dalam satu baris dalam file index.js .

Arsitektur untuk proyek dalam sampel ini adalah sebagai berikut:

projectDirectory

  • index.js
  • podcast.js
  • profile.js

index.js

const admin = require('firebase-admin');
const podcast = require('./podcast');
const profile = require('./profile');
admin.initializeApp();

exports.getPodcast = podcast.getPodcast();
exports.removeProfile = profile.removeProfile();

podcast.js

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

exports.getPodcast = () => functions.https.onCall(async (data, context) => {
      ...
      return { ... }
  });

Pola yang sama akan digunakan untuk removeProfilemetode dalam file profil .

Adam Hurwitz
sumber
7

Agar tetap sederhana (tetapi berfungsi), saya secara pribadi menyusun kode saya seperti ini.

Tata letak

├── /src/                      
   ├── index.ts               
   ├── foo.ts           
   ├── bar.ts           
└── package.json  

untuk

export const fooFunction = functions.database()......... {
    //do your function.
}

export const someOtherFunction = functions.database().......... {
    // do the thing.
}

bar.ts

export const barFunction = functions.database()......... {
    //do your function.
}

export const anotherFunction = functions.database().......... {
    // do the thing.
}

index.ts

import * as fooFunctions from './foo';
import * as barFunctions from './bar';

module.exports = {
    ...fooFunctions,
    ...barFunctions,
};

Berfungsi untuk direktori dari semua level bersarang. Cukup ikuti pola di dalam direktori juga.

zaidfazil
sumber
Saya tidak bisa melihat bagaimana ini bisa bekerja karena Firebase mendukung Node 6.11 saat ini yang tidak mendukung arahan impor ES6?
Aodh
Jika Anda menggunakan naskah, masalah seharusnya tidak pernah muncul. Saya melakukan port sebagian besar kode saya ke dalam naskah akhir-akhir ini.
zaidfazil
2
zaidfazil, Anda mungkin harus mencatat semua prasyarat dalam jawaban Anda. @ Asth, itu berfungsi jika Anda menggunakan Babel dengan cara yang sama seperti yang dijabarkan Konstantin dalam sebuah jawaban. stackoverflow.com/questions/43486278/…
PostureOfLearning
1
Terima kasih. ini bekerja dengan naskah dan simpul 6 :)
Ahmad Moussa
4
Daripada mengimpor dan mengekspor kembali dengan operator yang tersebar, tidak bisakah Anda hanya memiliki export * from './fooFunctions';dan export * from './barFunctions';di index.ts?
whatsthatitspat
5

Format ini memungkinkan titik masuk Anda untuk menemukan file fungsi tambahan, dan mengekspor setiap fungsi dalam setiap file, secara otomatis.

Script Titik Masuk Utama

Menemukan semua file .js di dalam folder fungsi, dan mengekspor setiap fungsi yang diekspor dari setiap file.

const fs = require('fs');
const path = require('path');

// Folder where all your individual Cloud Functions files are located.
const FUNCTIONS_FOLDER = './scFunctions';

fs.readdirSync(path.resolve(__dirname, FUNCTIONS_FOLDER)).forEach(file => { // list files in the folder.
  if(file.endsWith('.js')) {
    const fileBaseName = file.slice(0, -3); // Remove the '.js' extension
    const thisFunction = require(`${FUNCTIONS_FOLDER}/${fileBaseName}`);
    for(var i in thisFunction) {
        exports[i] = thisFunction[i];
    }
  }
});

Contoh Ekspor Beberapa Fungsi dari Satu File

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

const query = functions.https.onRequest((req, res) => {
    let query = req.query.q;

    res.send({
        "You Searched For": query
    });
});

const searchTest = functions.https.onRequest((req, res) => {
    res.send({
        "searchTest": "Hi There!"
    });
});

module.exports = {
    query,
    searchTest
}

Titik akhir yang dapat diakses http diberi nama dengan tepat

✔ functions: query: http://localhost:5001/PROJECT-NAME/us-central1/query
✔ functions: helloWorlds: http://localhost:5001/PROJECT-NAME/us-central1/helloWorlds
✔ functions: searchTest: http://localhost:5001/PROJECT-NAME/us-central1/searchTest

Satu file

Jika Anda hanya memiliki beberapa file tambahan (mis. Hanya satu), Anda dapat menggunakan:

const your_functions = require('./path_to_your_functions');

for (var i in your_functions) {
  exports[i] = your_functions[i];
}

Matthew Rideout
sumber
Bukankah ini memiliki kelebihan pada saat boot untuk setiap instance fungsi yang berputar?
Ayyappa
4

Jadi saya punya proyek ini yang memiliki fungsi latar belakang dan fungsi http. Saya juga memiliki tes untuk pengujian unit. CI / CD akan membuat hidup Anda lebih mudah ketika menggunakan fungsi cloud

Struktur folder

|-- package.json
|-- cloudbuild.yaml
|-- functions
    |-- index.js
    |-- background
    |   |-- onCreate
    |       |-- index.js
            |-- create.js
    |
    |-- http
    |   |-- stripe
    |       |-- index.js
    |       |-- payment.js
    |-- utils
        |-- firebaseHelpers.js
    |-- test
        |-- ...
    |-- package.json

Catatan: utils/ folder adalah untuk berbagi kode antar fungsi

fungsi / index.js

Di sini Anda bisa mengimpor semua fungsi yang Anda butuhkan dan mendeklarasikannya. Tidak perlu punya logika di sini. Itu membuatnya lebih bersih menurut saya.

require('module-alias/register');
const functions = require('firebase-functions');

const onCreate = require('@background/onCreate');
const onDelete = require('@background/onDelete');
const onUpdate = require('@background/onUpdate');

const tours  = require('@http/tours');
const stripe = require('@http/stripe');

const docPath = 'tours/{tourId}';

module.exports.onCreate = functions.firestore.document(docPath).onCreate(onCreate);
module.exports.onDelete = functions.firestore.document(docPath).onDelete(onDelete);
module.exports.onUpdate = functions.firestore.document(docPath).onUpdate(onUpdate);

module.exports.tours  = functions.https.onRequest(tours);
module.exports.stripe = functions.https.onRequest(stripe);

CI / CD

Bagaimana dengan memiliki integrasi dan penerapan berkelanjutan setiap kali Anda mendorong perubahan ke repo? Anda dapat memilikinya dengan menggunakan google google cloud build . Gratis sampai titik tertentu :) Periksa tautan ini .

./cloudbuild.yaml

steps:
  - name: "gcr.io/cloud-builders/npm"
    args: ["run", "install:functions"]
  - name: "gcr.io/cloud-builders/npm"
    args: ["test"]
  - name: "gcr.io/${PROJECT_ID}/firebase"
    args:
      [
        "deploy",
        "--only",
        "functions",
        "-P",
        "${PROJECT_ID}",
        "--token",
        "${_FIREBASE_TOKEN}"
      ]

substitutions:
    _FIREBASE_TOKEN: nothing
putri duyung
sumber
saya telah mengekspor seperti yang Anda katakan tetapi firebase menyebarkan mendeteksi satu yang pada akhirnya, misalnya: sesuai kode Anda hanya membutuhkan module.exports.stripe = functions.https.onRequest (stripe);
OK200
@ OK200 apa perintah yang Anda gunakan dengan baris perintah firebase? Untuk membantu Anda, saya perlu melihat beberapa kode
ajorquera
3

Ada cara yang cukup bagus untuk mengatur semua fungsi cloud Anda untuk jangka panjang. Saya melakukan ini baru-baru ini dan bekerja dengan sempurna.

Apa yang saya lakukan adalah mengatur setiap fungsi cloud dalam folder terpisah berdasarkan titik akhir pemicu mereka. Setiap nama fungsi cloud diakhiri dengan *.f.js. Misalnya, jika Anda memiliki onCreatedan onUpdatememicu user/{userId}/document/{documentId}maka buat dua file onCreate.f.jsdan onUpdate.f.jsdalam direktori functions/user/document/dan fungsi Anda akan dinamai userDocumentOnCreatedan userDocumentOnUpdatemasing - masing. (1)

Berikut adalah contoh struktur direktori:

functions/
|----package.json
|----index.js
/----user/
|-------onCreate.f.js
|-------onWrite.f.js
/-------document/
|------------onCreate.f.js
|------------onUpdate.f.js
/----books/
|-------onCreate.f.js
|-------onUpdate.f.js
|-------onDelete.f.js

Fungsi Sampel

const functions = require('firebase-functions');
const admin = require('firebase-admin');
const db = admin.database();
const documentsOnCreate = functions.database
    .ref('user/{userId}/document/{documentId}')
    .onCreate((snap, context) => {
        // your code goes here
    });
exports = module.exports = documentsOnCreate;

Index.js

const glob = require("glob");
const camelCase = require('camelcase');
const admin = require('firebase-admin');
const serviceAccount = require('./path/to/ServiceAccountKey.json');
try {
    admin.initializeApp({ credential: admin.credential.cert(serviceAccount),
    databaseURL: "Your database URL" });
} catch (e) {
    console.log(e);
}

const files = glob.sync('./**/*.f.js', { cwd: __dirname });
for (let f = 0, fl = files.length; f < fl; f++) {
    const file = files[f];
    const functionName = camelCase(file.slice(0, -5).split('/')); 
    if (!process.env.FUNCTION_NAME || process.env.FUNCTION_NAME === functionName) {
        exports[functionName] = require(file);
      }
}

(1): Anda dapat menggunakan nama yang Anda inginkan. Bagi saya, onCreate.f.js, onUpdate.f.js dll. Tampaknya lebih relevan dengan jenis pemicu mereka.

krhitesh
sumber
1
Pendekatan ini sangat bagus. Saya bertanya-tanya apakah mungkin untuk menyesuaikan untuk memungkinkan garis miring pada nama fungsi sehingga Anda dapat memisahkan versi api yang berbeda, misalnya (api v1, api v2, dll)
Alex Sorokoletov
Mengapa Anda ingin menyimpan berbagai versi fungsi cloud di bawah proyek yang sama? Meskipun Anda dapat melakukannya dengan sedikit mengubah struktur direktori, secara default index.js akan menyebarkan semua fungsi cloud kecuali Anda menggunakan secara selektif atau menggunakan kondisi-if di index.js Anda yang pada akhirnya akan mengacaukan kode Anda
krhitesh
1
Saya baik-baik saja dengan mengerahkan semuanya, saya hanya ingin versi fungsi yang saya letakkan (yang dipicu http)
Alex Sorokoletov
Saya berharap setiap pemicu http ada di *.f.jsfile sendiri . Paling tidak yang bisa Anda lakukan adalah mengganti nama file untuk setiap versi dengan menambahkan akhiran untuk membuatnya seperti *.v1.f.jsatau *.v2.f.jslain - lain (Asumsikan semua versi Anda dari semua pemicu http Anda aktif). Tolong beri tahu saya jika Anda memiliki solusi yang lebih baik.
krhitesh
1

Saya menggunakan bootloader vanilla JS untuk secara otomatis menyertakan semua fungsi yang ingin saya gunakan.

├── /functions
   ├── /test/
      ├── testA.js
      └── testB.js
   ├── index.js
   └── package.json

index.js (bootloader)

/**
 * The bootloader reads all directories (single level, NOT recursively)
 * to include all known functions.
 */
const functions = require('firebase-functions');
const fs = require('fs')
const path = require('path')

fs.readdirSync(process.cwd()).forEach(location => {
  if (!location.startsWith('.')) {
    location = path.resolve(location)

    if (fs.statSync(location).isDirectory() && path.dirname(location).toLowerCase() !== 'node_modules') {
      fs.readdirSync(location).forEach(filepath => {
        filepath = path.join(location, filepath)

        if (fs.statSync(filepath).isFile() && path.extname(filepath).toLowerCase() === '.js') {
          Object.assign(exports, require(filepath))
        }
      })
    }
  }
})

File index.js contoh ini hanya menyertakan direktori secara otomatis di dalam root. Itu bisa diperluas untuk berjalan direktori, kehormatan .gitignore, dll. Ini sudah cukup bagi saya.

Dengan file indeks di tempat, menambahkan fungsi baru itu sepele.

/test/testA.js

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

exports.helloWorld = functions.https.onRequest((request, response) => {
 response.send("Hello from Firebase!");
});

/test/testB.js

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

exports.helloWorld2 = functions.https.onRequest((request, response) => {
 response.send("Hello again, from Firebase!");
});

npm run serve hasil:

λ ~/Workspace/Ventures/Author.io/Firebase/functions/ npm run serve

> functions@ serve /Users/cbutler/Workspace/Ventures/Author.io/Firebase/functions
> firebase serve --only functions


=== Serving from '/Users/cbutler/Workspace/Ventures/Author.io/Firebase'...

i  functions: Preparing to emulate functions.
Warning: You're using Node.js v9.3.0 but Google Cloud Functions only supports v6.11.5.
✔  functions: helloWorld: http://localhost:5000/authorio-ecorventures/us-central1/helloWorld
✔  functions: helloWorld2: http://localhost:5000/authorio-ecorventures/us-central1/helloWorld2

Alur kerja ini cukup banyak hanya "tulis dan jalankan", tanpa harus memodifikasi file index.js setiap kali fungsi / file baru ditambahkan / dimodifikasi / dihapus.

Corey
sumber
tidakkah ini akan ada di awal yang dingin?
Ayyappa
1

Inilah jawaban sederhana jika Anda membuat fungsi cloud dengan naskah.

/functions
|--index.ts
|--foo.ts

Di dekat semua impor reguler Anda di bagian atas, cukup ekspor semua fungsi dari foo.ts.

export * from './foo';

Markymark
sumber