मैं कई फाइलों से कई कार्यों को तैनात करने के लिए फायरबेस के लिए क्लाउड फ़ंक्शंस कैसे संरचना करूं?


164

मैं फायरबेस के लिए एक से अधिक क्लाउड फंक्शन्स बनाना और एक ही समय में एक ही समय में उन सभी को तैनात करना चाहूंगा। मैं प्रत्येक फ़ंक्शन को एक अलग फ़ाइल में अलग करना भी चाहूंगा। वर्तमान में मैं कई कार्य बना सकता हूँ अगर मैं उन दोनों को index.js में रखता हूँ जैसे:

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

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

हालांकि मैं अलग-अलग फाइलों में फू और बार लगाना चाहूंगा। मैंने यह कोशिश की:

/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 में डाले बिना इसे पूरा करने का एक तरीका है?


1
@JPVentura। वास्तव में आप अच्छी तरह से नहीं समझते हैं। कृपया समझाएँ।
HuyLe

क्या इसे v1.0 के लिए अपडेट किया गया है? मेरे पास मुद्दे हैं: stackoverflow.com/questions/50089807/…
tccpg288

2
FYI करें, इस आधिकारिक फायरबेस फ़ंक्शन के उदाहरण में कई .jsफाइलें आयात की जाती हैं require: github.com/firebase/functions-samples/tree/master/…
xanderiel

यह मददगार हो सकता है: stackoverflow.com/questions/43486278/…
रमेश-एक्स

जवाबों:


126

सामान्य रूप से फायरबेस लोड नोड मॉड्यूल के लिए आह, क्लाउड फ़ंक्शंस, इसलिए यह काम करता है

संरचना:

/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) => {
    ...
};

1
क्या मैं उदाहरण के लिए फू मॉड्यूल में कई कार्य कर सकता हूं? यदि हां, तो इसे लागू करना बेहतर कैसे है?
अलेक्जेंडर खितेव

1
मुझे लगता है कि आप फू से अलग-अलग निर्यात किए गए कार्यों के लिए अलग-अलग संचालकों को सौंप सकते हैं: Export.bar = functions.database.ref ('/ foo')। onWrite (fooModule.barHandler); Export.baz = functions.database.ref ('/ bar')। onWrite (fooModule.bazHandler);
jasonsirota

44
मुझे यह समाधान पसंद नहीं है क्योंकि यह foo.js और bar.js से जानकारी (अर्थात् डेटाबेस पथ) को स्थानांतरित करता है। index.js में जो उन अलग-अलग फ़ाइलों को रखने के बिंदु को हरा देता है।
bvs

मैं @bvs से सहमत हूं, मुझे लगता है कि सिड के पास एक अच्छा तरीका है। मैं इसे स्पष्ट रूप से प्रत्येक मॉड्यूल को निर्यात करके संशोधित करने जा रहा हूं। index.ts को सुपर स्पष्ट करने के लिए निर्यात करें। उदाहरण के लिए "" ./uthenticationFunctions "
Alan

2
मुझे लगता है कि मेरा मूल प्रश्न केवल 1 प्रोजेक्ट के साथ कई फ़ंक्शन को इंडेक्स में काम करने के बिना तैनात करने के बारे में था। जेएस फ़ाइल, जहां और कैसे आप डेटाबेस की जानकारी पास करते हैं, यह गुंजाइश नहीं है। क्या यह मुझे था, मैं शायद एक अलग मॉड्यूल बनाऊंगा जो डेटाबेस एक्सेस को नियंत्रित करता है और इसे foo.js और bar.js में अलग से आवश्यकता होती है, लेकिन यह एक शैलीगत निर्णय है।
jasonsirota

75

@Ajonsirota द्वारा जवाब बहुत मददगार था। लेकिन यह अधिक विस्तृत कोड को देखने के लिए उपयोगी हो सकता है, विशेष रूप से HTTP ट्रिगर कार्यों के मामले में।

@ Jasonsirota के उत्तर के समान संरचना का उपयोग करके, आप कह सकते हैं कि दो अलग-अलग फ़ाइलों में दो अलग-अलग 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'); 
}

Index.js में वर्तमान संरचना मेरे लिए अच्छी तरह से काम नहीं करती थी। मुझे जो करना था, वह पहले फायरबेस मॉड्यूल को इंपोर्ट करना था, फिर ऐप को इनिशियलाइज़ करना और फिर दूसरे फोल्डर से फंक्शन्स को इम्पोर्ट करना था। इस तरह मेरा ऐप पहले इनिशियलाइज़ करता है, ऑथेंटिकेट करता है, जो भी हो और फिर उन फंक्शन्स को इम्पोर्ट करता है जिन्हें ऐप को पहले से इनिशियलाइज़ करने की ज़रूरत होती है।
टनकटाटा

47

अपडेट: इस डॉक्टर को मदद करनी चाहिए , मेरा जवाब इस डॉक्टर से पुराना है।


यहां बताया गया है कि मैंने किस तरह से इसे टाइपस्क्रिप्ट के साथ किया है:

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

मुझे इस काम को करने के लिए दो चेतावनी देकर इसे पेश करना चाहिए:

  1. index.ts में आयात / निर्यात मामलों का क्रम
  2. db एक अलग फाइल होनी चाहिए

बिंदु संख्या 2 के लिए मुझे यकीन नहीं है कि क्यों। Secundo आप सूचकांक, मुख्य और डाटाबेस के अपने विन्यास का सम्मान करना चाहिए वास्तव में (कम से कम इसे आज़माने के लिए)।

index.ts : निर्यात से संबंधित है। मुझे यह इंडेक्स के निर्यात के साथ सौदा करने के लिए क्लीनर लगता है।

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

main.ts : आरंभीकरण के साथ सौदा।

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

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

db.ts : बस db को reexporting कर रहा है ताकि इसका नाम इससे छोटा होdatabase()

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);
}

आपका tsconfig कैसा दिखता है? मैं एक डिस्टर्ब फोल्डर में कैसे संकलित कर सकता हूं और gcloud फ़ंक्शन को बता सकता हूं कि मेरा index.js कहां है? क्या आपके पास जीथब पर अपना कोड है? :)
बोरिंग

@ choopage-JekBao क्षमा करें यह एक लंबा समय हो गया है, मेरे पास अब परियोजना नहीं है। अगर मुझे सही से याद है तो आप फायरबेस को एक डायरेक्टरी (जो डिफ़ॉल्ट रूप से सार्वजनिक है) को कॉन्फ़िगर कर सकते हैं। मैं गलत हो सकता है, क्योंकि यह एक वर्ष से अधिक हो गया है
Ced

अरे @ इष्ट - db.tsअंदर जाने की सामग्री क्यों नहीं main.ts(व्यवस्थापक तात्कालिकता के बाद?)। या आप सिर्फ स्पष्टता / सरलता के लिए इस तरह से अलग हो गए हैं?
dsg38

1
@ dsg38 यह बहुत समय पहले पोस्ट किया गया था, मैं वास्तव में यह नहीं देखता कि यह एक अलग फाइल में क्यों होना चाहिए जो अब उत्तर को देख रहा है .. मुझे लगता है कि यह स्पष्टता के लिए था
Ced

21

नोड 8 एलटीएस के साथ अब क्लाउड / फायरबेस फंक्शंस के साथ उपलब्ध हैं जो आप प्रसार ऑपरेटरों के साथ कर सकते हैं:

/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);
  });

मुझे आश्चर्य है कि अगर आयात की बढ़ती संख्या ने प्रत्येक फ़ंक्शन की ठंड शुरू कर दी या यदि अलग-अलग विकसित कई पूरी तरह से अलग किए गए मॉड्यूल होने चाहिए?
साइमन फकीर

2
मुझे unexpected token ...index.js के अंदर एक एस्लिंट पार्टिंग त्रुटि मिलती है ।
थॉमस

शायद आप नोड 8 का उपयोग नहीं कर रहे हैं
ल्यूक पिगेटी

@SimonFakir अच्छा सवाल। क्या आपने इसके बारे में कुछ पाया है?
अपरेशकोव

@atereshkov हां, मुझे अनुरोधित फ़ंक्शन को लोड करने का एक तरीका मिला, जिसमें नीचे दिए गए उत्तर के समान "process.env.FUNCTION_NAME" का उपयोग करके निर्भरताएं शामिल हैं। मैं अपने रेपो को संदर्भ के रूप में भी साझा कर सकता हूं यदि आप मुझसे संपर्क कर रहे हैं।
साइमन फकीर

15

सरल रखने के लिए (लेकिन काम करता है), मैंने अपने कोड को व्यक्तिगत रूप से इस तरह संरचित किया है।

ख़ाका

├── /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.
}

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';

किसी भी नेस्टेड स्तर की निर्देशिका के लिए काम करता है। बस निर्देशिका के अंदर पैटर्न का पालन करें।

@zaidfazil जवाब का श्रेय


1
यह टाइपस्क्रिप्ट, धन्यवाद के लिए सबसे सरल उत्तरों में से एक है। आप उदाहरण के लिए फायरबेस डेटाबेस के एक एकल इंस्टेंटेशन के साथ कैसे सामना करते हैं? admin.initializeApp(functions.config().firestore) const db = admin.firestore();आप इसे कहां रखते हैं और आप इसे फू और बार में कैसे संदर्भित करते हैं?
elprl

अरे - db.tsअंदर जाने की सामग्री क्यों नहीं मिल सकती index.ts(व्यवस्थापक तात्कालिकता के बाद?)। या आप सिर्फ स्पष्टता / सरलता के लिए इस तरह से अलग हो गए हैं?
dsg38

@ dsg38 आप सभी को एक साथ मिला सकते हैं, इससे यह स्पष्ट हो जाता है
रेजा

10

बाबेल / प्रवाह के मामले में यह इस तरह दिखेगा:

निर्देशिका लेआउट

.
├── /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 - मुख्य निर्यात)

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


src/db.js - पोस्टग्रेज के लिए क्लाउड एसक्यूएल क्लाइंट

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 - फायरबेस फायरस्टार क्लाइंट

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 - समारोह बी

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

9

bigcodenerd.org रूपरेखा का एक सरल आर्किटेक्चर पैटर्न है, जिसमें अलग-अलग फाइलों में अलग-अलग तरीके हैं और इंडेक्स के भीतर एक लाइन में निर्यात किया गया है। फ़ाइल के ।

इस नमूने में परियोजना के लिए वास्तुकला निम्नलिखित है:

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में विधि के लिए समान पैटर्न का उपयोग किया जाएगा ।


7

सरल रखने के लिए (लेकिन काम करता है), मैंने अपने कोड को व्यक्तिगत रूप से इस तरह संरचित किया है।

ख़ाका

├── /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.
}

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,
};

किसी भी नेस्टेड स्तर की निर्देशिका के लिए काम करता है। बस निर्देशिका के अंदर पैटर्न का पालन करें।


मैं यह नहीं देख सकता कि यह संभवत: कैसे काम कर सकता है क्योंकि फायरबेस एनओडी 6.11 का समर्थन करता है जो वर्तमान में ईएस 6 आयात निर्देशों का समर्थन नहीं करता है?
अयोध

यदि आप टाइपस्क्रिप्ट का उपयोग कर रहे हैं, तो समस्या कभी भी उत्पन्न नहीं होनी चाहिए। मैंने अपना अधिकांश कोड टाइपस्क्रिप्ट में हाल ही में पोर्ट किया।
zaidfazil

2
zaidfazil, आपको अपने उत्तर में किसी भी पूर्व-आवश्यकता को नोट करना चाहिए। @ ओह, यह काम करता है यदि आप बैबल का उपयोग उसी तरह करते हैं जैसे कि कॉन्स्टेंटिन ने एक उत्तर में उल्लिखित किया है। stackoverflow.com/questions/43486278/…
PostureOfLearning

1
धन्यवाद। यह टाइपस्क्रिप्ट और नोड 6 के साथ काम करता है :)
अहमद मौसा

4
प्रसार ऑपरेटरों के साथ आयात और पुन: निर्यात के बजाय, क्या आप अभी export * from './fooFunctions';और export * from './barFunctions';index.ts में नहीं कर सकते हैं ?
व्हाट्सएप्सिट्स

5

यह प्रारूप आपके प्रवेश-बिंदु को अतिरिक्त फ़ंक्शन फ़ाइलों को खोजने की अनुमति देता है, और प्रत्येक फ़ाइल के भीतर प्रत्येक फ़ंक्शन को स्वचालित रूप से निर्यात करता है।

मुख्य प्रवेश बिंदु लिपि

फ़ंक्शन फ़ोल्डर के अंदर सभी .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];
}


क्या यह हर फंक्शन इंस्टेंस के लिए बूट पर ओवरलोड नहीं होगा जो घूमता है?
अय्यप्पा

4

इसलिए मेरे पास यह परियोजना है जिसमें पृष्ठभूमि फ़ंक्शन और 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

नोट: utils/ फ़ोल्डर फ़ंक्शन के बीच शेयर कोड के लिए है

कार्य / index.js

यहां आप अपनी ज़रूरत के सभी कार्यों को आयात कर सकते हैं और उन्हें घोषित कर सकते हैं। यहां तर्क की जरूरत नहीं है। यह मेरी राय में क्लीनर बनाता है।

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);

सीआई / सीडी

जब आप रेपो में अपने बदलावों को आगे बढ़ाते हैं तो हर बार कंटीन्यू इंटीग्रेशन और परिनियोजन कैसे होता है? आप google google cloud build का उपयोग करके इसे पा सकते हैं । यह निश्चित बिंदु तक मुफ्त है :) इस लिंक की जाँच करें ।

./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

जैसा कि आपने कहा मैंने निर्यात किया है, लेकिन फायरबेस तैनात एक का पता लगाता है जो अंत में है, पूर्व: आपके कोड के अनुसार यह केवल मॉड्यूल लेता है। xports.stripe = functions.https.onRequest (स्ट्राइप);
200 पर OK200

@ OK200 जो कमांड आप फायरबेस कमांड लाइन के साथ प्रयोग कर रहे हैं वह क्या है? आपकी सहायता के लिए, मुझे कुछ कोड देखने की आवश्यकता होगी
ajorquera

3

लंबी अवधि के लिए अपने सभी क्लाउड फ़ंक्शंस को व्यवस्थित करने का एक अच्छा तरीका है। मैंने हाल ही में यह किया है और यह त्रुटिपूर्ण रूप से काम कर रहा है।

मैंने जो किया वह प्रत्येक क्लाउड फ़ंक्शन को उनके ट्रिगर एंडपॉइंट के आधार पर अलग-अलग फ़ोल्डरों में व्यवस्थित किया। हर क्लाउड फ़ंक्शन फ़ाइल नाम के साथ समाप्त होता है *.f.js। उदाहरण के लिए, यदि आपके पास था onCreateऔर onUpdateचालू होता है, user/{userId}/document/{documentId}तो दो फाइलें बनाएं onCreate.f.jsऔर onUpdate.f.jsनिर्देशिका में functions/user/document/और आपके फ़ंक्शन का नाम 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;

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): आप अपने इच्छित किसी भी नाम का उपयोग कर सकते हैं। मेरे लिए, onCreate.f.js, onUpdate.f.js आदि इस तरह के ट्रिगर के लिए अधिक प्रासंगिक लगते हैं।


1
यह दृष्टिकोण वास्तव में अच्छा है। मैं सोच रहा था कि क्या फ़ंक्शन नामों में स्लैश की अनुमति देने के लिए समायोजित करना संभव है ताकि आप अलग-अलग एपीआई संस्करणों को अलग कर सकें, उदाहरण के लिए (एपीआई v1, एपीआई वी 2, आदि)
एलेक्स सोरोकलेटोव

आप एक ही परियोजना के तहत क्लाउड फ़ंक्शन के विभिन्न संस्करणों को क्यों रखना चाहेंगे? हालाँकि आप यह कर सकते हैं कि निर्देशिका संरचना को थोड़ा बदलकर, डिफ़ॉल्ट index.js द्वारा सभी क्लाउड फ़ंक्शंस को तब तक तैनात किया जाएगा जब तक कि आप चयन नहीं करते या यदि आपके index.js में शर्तों का उपयोग करते हैं जो अंततः आपके कोड को समाप्त कर देंगे
khhitesh

1
मैं सब कुछ तैनात करने के साथ ठीक हूं, मैं बस उन कार्यों को संस्करण देना चाहता हूं जो मैंने डाल दिए (http ट्रिगर)
एलेक्स सोरोकोलेटोव

मैं उम्मीद कर रहा हूँ कि हर http ट्रिगर अपनी *.f.jsफ़ाइल में है। कम से कम आप ऐसा कर सकते हैं कि हर संस्करण के लिए फ़ाइल का नाम बदलकर प्रत्यय लगाकर इसे कुछ इस तरह *.v1.f.jsसे बनाया जाए *.v2.f.jsआदि ( जैसे कि आपके सभी http ट्रिगर के सभी संस्करण लाइव हैं)। कृपया मुझे बताएं कि क्या आपके पास बेहतर समाधान है।
khhitesh 5

1

मैं वेनिला 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 रूट के भीतर केवल ऑटो-डायरेक्टरी निर्देशिकाओं को फाइल करता है। यह निर्देशिका, सम्मान, .ignignore, आदि के लिए विस्तारित किया जा सकता है, हालांकि यह मेरे लिए पर्याप्त था।

सूचकांक फ़ाइल के स्थान पर, नए कार्यों को जोड़ना तुच्छ है।

/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 पैदावार:

λ ~/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 फ़ाइल को संशोधित किए बिना।


यह ठंड शुरू होने पर नहीं होगा?
अय्यप्पा

1

यदि आप टाइपस्क्रिप्ट के साथ क्लाउड फ़ंक्शंस बना रहे हैं, तो यहां एक सरल उत्तर है।

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

शीर्ष पर अपने सभी नियमित आयातों के पास बस से सभी कार्यों का निर्यात करें foo.ts

export * from './foo';


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.