나를 만들고 싶은 여러 클라우드 기능에 대한 중포 기지하고 배포하는 동시에 모두 중 하나에서 프로젝트입니다. 또한 각 기능으로 별도의 파일입니다. 현재 내가 만들 수 있는 여러 기능을 넣으면 그들을 둘 다에 index.js 와 같은:
exports.foo = functions.database.ref('/foo').onWrite(event => {
...
});
exports.bar = functions.database.ref('/bar').onWrite(event => {
...
});
그러나 넣고 싶은 foo 과 바에서 별개의 파일이 있습니다. 나이:
/functions
|--index.js (blank)
|--foo.js
|--bar.js
|--package.json
가 foo.js 가
exports.foo = functions.database.ref('/foo').onWrite(event => {
...
});
고 bar.js 가
exports.bar = functions.database.ref('/bar').onWrite(event => {
...
});
는 방법이 있을 수행하고없이 모든 기능에 index.js?
Ah,클라우드 기능을 로드 중포 기지 노드 모듈을 일반적으로,그래서 이 작품
구조:
/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) => {
...
};
대답하여@jasonsirota 매우 도움이 되었습니다. 하지만 그것이 유용할 수 있습니다 보다 상세한 코드의 경우 특히 HTTP 트리거 기능이 있다.
를 사용하여 동일한 구조를로에서@jasonsirota's 응답을 말할 수 있습니다 당신이 원하는 두 가지 별도의 HTTP 트리거 기능에 두 개의 서로 다른 파일은:
디렉토리 구조로 구성되어 있다:
/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');
}
업데이트:이 문서는 데 도움이해야,내 대답은 이전보다 이 doc.
여기에 내가 어떻게 personnally 그것으로 호환되지 않:
/functions
|--src
|--index.ts
|--http-functions.ts
|--main.js
|--db.ts
|--package.json
|--tsconfig.json
자이 서문을 제공하여 두 경고 이렇게 하려면 다음을 수행합니다.
에 대한 지점에 2 번 나는'm 을 확인하세요. Secundo 을 존중해야한 내 구성을 인덱스,주요 db정확히(적어도 그것을 시도하).
index.ts:상품 수출합니다. 나는 그것을 찾을 깨끗하게입니다.ts 처리로 수출하고 있습니다.
// main must be before functions
export * from './main';
export * from "./http-functions";
습니다.ts:상품과 함께 초기화.
import { config } from 'firebase-functions';
import { initializeApp } from 'firebase-admin';
initializeApp(config().firebase);
export * from "firebase-functions";
db.ts:그냥 reexporting db 그래서 그것의 이름보다 짧은데이터베이스()
import { database } from "firebase-admin";
export const db = database();
http-능합니다.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);
}
노드 8LTS 으로 사용할 수 있 클라우드/중포 기지 기능이 다음을 수행할 수 있습니다으로 확산 운영자:
"engines": {
"node": "8"
},
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
};
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);
});
는 경우에는Babel/Flow그 다음과 같이 보일 것입니다.
.
├── /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
-주요 수출(s)export * from './someFuncA.js';
export * from './someFuncB.js';
src/db.js
클라우드 SQL 클라이언트에 대한 Postgresimport { 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
-중포 기지 Firestore 클라이언트import firebase from 'firebase-admin';
import { config } from 'firebase-functions';
firebase.initializeApp(config().firebase);
export default firebase.firestore();
src/someFuncA.js
-기능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
능 Bimport { 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" } }]],
}
중포 기지.json
{
"functions": {
"source": ".",
"ignore": [
"**/node_modules/**"
]
}
}
패키지입니다.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
을 보관한 간단한(하지만 작업),나 개인적으로 구축된 내 코드는 다음과 같다.
레이아웃
├── /src/
│ ├── index.ts
│ ├── foo.ts
│ ├── bar.ts
| ├── db.ts
└── package.json
foo.ts
import * as functions from 'firebase-functions';
export const fooFunction = functions.database()......... {
//do your function.
}
export const someOtherFunction = functions.database().......... {
// do the thing.
}
됩니다.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';
작품을 위해 디렉토리에는 중첩된 수준입니다. 그냥 따라 패턴 내부에 디렉토리 too.
신용을@zaidfazil 응답
을 보관한 간단한(하지만 작업),나 개인적으로 구축된 내 코드는 다음과 같다.
레이아웃
├── /src/
│ ├── index.ts
│ ├── foo.ts
│ ├── bar.ts
└── package.json
foo.ts
export const fooFunction = functions.database()......... {
//do your function.
}
export const someOtherFunction = functions.database().......... {
// do the thing.
}
됩니다.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,
};
작품을 위해 디렉토리에는 중첩된 수준입니다. 그냥 따라 패턴 내부에 디렉토리 too.
이 형식을 사용하 항목점을 찾을 추가기능 파일을 내보내 각 기능에 있는 각 파일을 자동으로 합니다.
주요 진입 점 스크립트
모두 찾습니다.js 파일 내부에는 함수의 폴더,그리고 수출액은 각 기능에서 내보내 각자 파일입니다.
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];
}
}
});
를 들어 내보내기의 여러 기능을 하나의 파일에서
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
}
http 끝점에 액세스할 수 있는 적절하게 이름
✔ 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
하나의 파일
는 경우에 당신은 단지 몇 가지 추가적인 파일을(예를 들어 단지 중 하나)사용할 수 있습니다:
const your_functions = require('./path_to_your_functions');
for (var i in your_functions) {
exports[i] = your_functions[i];
}
bigcodenerd.org윤곽's 간단한 건축에서 패턴을 가지기 위해 방법으로 분리되는 다른 파일에서 내보낸하나의 선에 index.js 파일입니다.
건축물 프로젝트에서 이 예제는 다음과 같다:
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 { ... }
});
동일한 패턴에 사용할 수 있removeProfile
방법에 profile 파일입니다.
거기에 아주 좋은 방법을 구성하는 모든 클라우드 기능에 대한 장기적이다. 나이지를 받으실 수 있습니다 그것은 완벽하게 작동.
무엇이었을 정리 각 클라우드 기능에 별도의 폴더에 따라 자신의 트리거합니다. 모든 클라우드 기능으로 끝나는 파일이름*.f.js
. 예를 들어 있다면 당신은onCreate
과onUpdate
트리거에서사용자/{userId}/document/{documentId}
다음에 파일 두개를 만들어onCreate.f.js
및onUpdate.f.js
디렉터리에서기능이/사용자/문서
와 함수 이름이 지정됩니다userDocumentOnCreate
과userDocumentOnUpdate
각각합니다. (1)
샘플렉토리 구조:
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
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;
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):모든 이름을 사용할 수 있습을 원합니다. 나 onCreate.f.js,onUpdate.f.js etc. 보상에 관련된 종류의 트리거를 그들이 있습니다.
그래서 나는 이 프로젝트는 배경 기능과 http 기능입니다. 도 테스트에 대한 단위 테스트입니다. CI/CD 를 만들 것입니다 당신의 인생을 더 쉽게 배포할 때 클라우드 기능
|-- 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
참고:출력/
폴더 공유를 위한 코드 사이의 함수
당신은 여기 있습니다 그냥 가져올 필요한 모든 기능 및 선언합니다. 가 필요 없는 논리니다 여기에. 그것은 청소기 내에서 의견입니다. ``javascript 을 필요로('module-alias/register'); const 기능=필요로('중포 기지-기');
const onCreate=필요로('@배경/onCreate'); const onDelete=필요로('@배경/onDelete'); const onUpdate=필요로('@배경/onUpdate');
const 투어=필요로('@http/투어'); const 스트라이프=필요로('@http/스트라이프');
const docPath='tours/{tourId}';
모듈입니다.로 수출하고 있습니다.onCreate=능합니다.firestore.문서(docPath).onCreate(onCreate); 모듈입니다.로 수출하고 있습니다.onDelete=능합니다.firestore.문서(docPath).onDelete(onDelete); 모듈입니다.로 수출하고 있습니다.onUpdate=능합니다.firestore.문서(docPath).onUpdate(onUpdate);
모듈입니다.로 수출하고 있습니다.tours=능합니다.https.onRequest(여행); 모듈입니다.로 수출하고 있습니다.스트라이프=능합니다.https.onRequest(스트라이프); ``
는 방법에 대해 갖는 연속적인 통합 및 배포를 모든 시간에 당신이 당신을 변경하 repo? 수 있습니다 당신은 그것을 사용하여 googlegoogle 클라우드 빌드. It's 무료될 때까지 특정 시점:)이 확인link.
./cloudbuild.yaml ``yaml 단계: -이름:"gcr.io/클라우드 빌더/npm" args:["run","설치 기능이"] -이름:"gcr.io/클라우드 빌더/npm" args:["시험"] -이름:"gcr.io/${PROJECT_ID}/중포 기지" args: [ "deploy", "-만", "기", "-P", "${PROJECT_ID}", "--토큰", "${_FIREBASE_TOKEN}" ]
대체: _FIREBASE_TOKEN:아무것도 ``
내가 사용하는 바닐라 JS 부트로더가 자동 모두 포함 기능을 사용하고 싶다.
├── /functions
│ ├── /test/
│ │ ├── testA.js
│ │ └── testB.js
│ ├── index.js
│ └── package.json
index.js(부트로더)
/**
* 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))
}
})
}
}
})
이 예제 index.js 파일이 자동으로 포함되어 있는 디렉토리 안에 뿌리입니다. 그것은 확장 될 수 있을 걸 디렉토리,영광입니다.gitignore,etc. 이 나를 위해 충분했지만.
Index 파일에 추가하는 새로운 기능을 하는 것입니다.
/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 실행 봉사하
수익률:
λ ~/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
이 워크플로는 거의 그냥"쓰고 실행되",수정하지 않고 index.js 매번 파일을 새로운 기능/파일을 수정/추가/제거됩니다.
보냈던 시간이 많이 찾고,동일하고 나가는 것이 생각하는 가장 좋은 방법 그것을 달성하기 위해(I'm 사용 [email protected]):
https://codeburst.io/organizing-your-firebase-cloud-functions-67dc17b3b0da
아 땀;)