আমি একাধিক ফাইল থেকে একাধিক ফাংশন মোতায়েন করতে ফায়ারবাসের জন্য মেঘ ফাংশনগুলি কীভাবে গঠন করব?


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

এবং বার.জেএস হয়

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

সূচি.জেজে সমস্ত ফাংশন না রেখে এটি সম্পাদনের কোনও উপায় আছে কি?


1
@JPVentura। সত্যিই আপনাকে ভাল বুঝতে পারছি না। দয়া করে ব্যাখ্যা করুন.
হুইল

এটি কি ভি 1.0 এর জন্য আপডেট করা হয়েছে? : আমি বিষয় হচ্ছে stackoverflow.com/questions/50089807/...
tccpg288

2
এফওয়াইআই, এই অফিশিয়াল ফায়ারবেস ফাংশন উদাহরণে বেশ কয়েকটি .jsফাইলের মাধ্যমে আমদানি করা হয়েছে require: github.com/firebase/function-sams/tree/master/…
xanderiel

এটি সহায়ক হতে পারে: স্ট্যাকওভারফ্লো.com
রমেশ-এক্স

উত্তর:


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
আমি উদাহরণস্বরূপ foo মডিউল বিভিন্ন কাজ করতে পারি? যদি তা হয় তবে এটি কার্যকর করা আরও কীভাবে ভাল?
আলেকজান্ডার খিতেভ

1
আমি মনে করি আপনি এবং foo থেকে বিভিন্ন রফতানি ফাংশনগুলিতে বিভিন্ন হ্যান্ডলারগুলি বরাদ্দ করতে পারেন: রফতানি.বার = ফাংশন.ড্যাটাসে.আরফ ('/ foo')। OnWrite (fooModule.barHandler); রপ্তানি.বাজ = ফাংশন.ড্যাটাস.আরফ ('/ বার')
জেসনসিরোটা

44
আমি এই সমাধানটি পছন্দ করি না কারণ এটি foo.js এবং বার.জেস থেকে সূচি.জগুলিতে তথ্য (অর্থাত্ ডাটাবেস পাথগুলি) সরিয়ে নিয়ে যায় যা এই জাতীয় ফাইলগুলির বিন্দুতে পরাস্ত করে kind
বিভিএস

আমি @bvs এর সাথে একমত, আমার মনে হয় সিডের একটি ভাল পদ্ধতির রয়েছে। আমি সূচক স্পষ্ট করে প্রতিটি মডিউলকে রপ্তানি করে কিছুটা সংশোধন করতে যাচ্ছি। সূচকগুলিকে সুপার স্পষ্ট করে যেমন "./authenticationFunifications" থেকে "নতুন ব্যবহারকারী" রফতানি করতে
অ্যালান

2
আমি মনে করি আমার মূল প্রশ্নটি কেবল সূচি.জেএস ফাইলটিতে ফাংশন না রেখে 1 টি প্রকল্পের সাথে একাধিক ফাংশন স্থাপন করা সম্পর্কে ছিল, আপনি কোথায় এবং কীভাবে ডাটাবেস তথ্য পাস করবেন তা সুযোগের মধ্যে নেই। এটি যদি আমি থাকতাম তবে আমি সম্ভবত একটি পৃথক মডিউল তৈরি করতাম যা ডাটাবেস অ্যাক্সেসকে নিয়ন্ত্রণ করে এবং foo.js এবং bar.js এ পৃথকভাবে প্রয়োজন, তবে এটি একটি স্টাইলিস্টিক সিদ্ধান্ত।
জেসনসিরোটা

75

@ জেসনসিরোটার উত্তরটি খুব সহায়ক ছিল। তবে বিশেষত এইচটিটিপি ট্রিগারযুক্ত ফাংশনগুলির ক্ষেত্রে আরও বিশদ কোডটি দেখতে দরকারী হতে পারে।

@ জেসনসিরোটার উত্তরের মতো একই কাঠামোটি ব্যবহার করে, আপনাকে বলতে দিন যে আপনি দুটি পৃথক ফাইলে দুটি পৃথক এইচটিটিপি ট্রিগার ফাংশন রাখতে চান:

ডিরেক্টরি কাঠামো:

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

সূচি.জেজে বর্তমান কাঠামো আমার পক্ষে ভালভাবে কাজ করে নি। আমাকে যা করতে হয়েছিল তা হ'ল প্রথমে ফায়ারবেস মডিউলগুলি আমদানি করা, তারপরে অ্যাপ্লিকেশনটি আরম্ভ করা এবং তারপরে অন্যান্য ফোল্ডারগুলি থেকে ফাংশনগুলি আমদানি করা। এইভাবে আমার অ্যাপ্লিকেশন প্রথমে সূচনা করে, প্রমাণীকরণ করে, যাই হোক না কেন এবং তারপরে অ্যাপ্লিকেশনটি আগে শুরু করার প্রয়োজন এমন ফাংশনগুলি আমদানি করে।
টোনকাটাটা

47

আপডেট: এই দস্তাবেজের সহায়তা করা উচিত , আমার উত্তরটি এই দস্তাবেজের চেয়ে পুরানো।


টাইপস্ক্রিপ্ট দিয়ে আমি ব্যক্তিগতভাবে এটি কীভাবে করেছি তা এখানে:

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

এই কাজটি করার জন্য দুটি সতর্কতা দিয়ে আমাকে এটির উপস্থাপনা করুন:

  1. সূচিপত্রগুলিতে আমদানি / রফতানি বিষয়গুলির ক্রম
  2. ডিবি অবশ্যই পৃথক ফাইল হতে হবে

2 নম্বর পয়েন্টের জন্য আমি নিশ্চিত না কেন why সেকেন্ডো আপনার আমার সূচকটির মূল কনফিগারেশনটি সম্মান করা উচিত, প্রধান এবং ডিবি ঠিক (অন্তত এটি চেষ্টা করার জন্য)।

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 : কেবল নামটি সংক্ষিপ্ত করে ডিবিকে পুনরায় রপ্তানি করা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 ফাংশনগুলি জানতে পারি যে আমার সূচক.জগুলি কোথায়? গিথুব এ আপনার কোড আছে? :)
bersling

@ চুপেজ-জেকবাও দুঃখিত, অনেক দিন হয়ে গেছে, আমার আর প্রকল্প নেই। যদি আমি সঠিকভাবে স্মরণ করি তবে আপনি ফায়ারবেস কনফিগারেশনকে একটি ডিরেক্টরি দিতে পারেন (যা ডিফল্টরূপে সর্বজনীন)। এক বছরেরও বেশি সময় হয়েছে বলে আমি ভুল হতে পারি
সিড

আরে @ced - কেন সামগ্রীগুলি db.tsভিতরে যেতে পারে না main.ts(অ্যাডমিন তাত্ক্ষণিকতার পরে?)। বা আপনি কি স্পষ্টতা / সরলতার জন্য এইভাবে আলাদা হয়ে গেছেন?
dsg38

1
@ dsg38 এটি অনেক আগে পোস্ট করা হয়েছিল, উত্তরটি এখন দেখার জন্য কেন এটি আলাদা ফাইলের মধ্যে হওয়া উচিত তা আমি সত্যিই দেখতে পাই না .. আমি মনে করি এটি স্পষ্টতার জন্য ছিল
সিড

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
আমি index.js এর unexpected token ...ভিতরে একটি এসিলিন্ট পার্টিং ত্রুটি পেয়েছি।
থোমাস

সম্ভবত আপনি নোড 8 ব্যবহার করছেন না
লুক পিঘেটি

@ সিমন ফকির ভাল প্রশ্ন। আপনি এটি সম্পর্কে কিছু খুঁজে পেয়েছেন?
আটারেশকভ

@atereshkov হ্যাঁ আমি নীচের উত্তরের সাথে অনুরূপ "প্রক্রিয়া.এনভি.ফুনક્શન_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 রূপরেখা আদেশ পদ্ধতি আছে করার জন্য একটি সহজ স্থাপত্য প্যাটার্ন বিভিন্ন ফাইল মধ্যে পৃথক রপ্তানী এক লাইন মধ্যে 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পদ্ধতিটির জন্য একই প্যাটার্নটি ব্যবহৃত হবে।


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 আমদানির নির্দেশকে সমর্থন করে না?
আউদ

আপনি যদি টাইপ স্ক্রিপ্ট ব্যবহার করছেন তবে সমস্যাটি কখনই উত্থিত হওয়া উচিত নয়। আমি আমার কোড বেশিরভাগ টাইপ স্ক্রিপ্টে ইদানীং পোর্ট করেছি।
জায়েদফাজিল

2
জায়েদফাজিল, আপনার উত্তরটিতে সম্ভবত কোনও পূর্ব-প্রয়োজনীয়তা অবশ্যই নোট করা উচিত। @ অওহ, আপনি যদি বাবেলকে একইভাবে কনস্ট্যান্টিনের উত্তরে বর্ণিতভাবে ব্যবহার করেন তবে এটি কাজ করবে। stackoverflow.com/questions/43486278/...
PostureOfLearning

1
ধন্যবাদ. এটি টাইপস্ক্রিপ্ট এবং নোড :) এর সাথে কাজ করেছে :)
আহমদ মুসা

4
আমদানি করা এবং স্প্রেড অপারেটরগুলির সাথে পুনরায় রফতানির পরিবর্তে, আপনি কি কেবলমাত্র export * from './fooFunctions';এবং export * from './barFunctions';ইনডেক্স.সেটসে থাকতে পারবেন না ?
হোয়াটহিটসপত

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

সুতরাং আমার কাছে এই প্রকল্পটির ব্যাকগ্রাউন্ড ফাংশন এবং এইচটিপি ফাংশন রয়েছে। ইউনিট পরীক্ষার জন্য আমারও পরীক্ষা আছে। ক্লাউড ফাংশন স্থাপন করার সময় সিআই / সিডি আপনার জীবনকে আরও সহজ করে তুলবে

ফোল্ডার কাঠামো

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

সি আই / সিডি

প্রতিবার আপনার পরিবর্তনগুলি রেপোতে চাপানোর সময় কন্টিনোস ইন্টিগ্রেশন এবং মোতায়েনের বিষয়ে কীভাবে? গুগল গুগল ক্লাউড বিল্ড ব্যবহার করে আপনি এটি পেতে পারেন । নির্দিষ্ট বিন্দু অবধি এটি নিখরচায় :) এই লিঙ্কটি চেক করুন

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

আমি যেমন বলেছিলাম তেমনই আমি রফতানি করেছি তবে ফায়ারবেস অন্তর্ভুক্তটিকে সনাক্ত করে, উদাহরণস্বরূপ: আপনার কোড অনুসারে এটি কেবল মডিউল.এক্সপোর্টস.স্ট্রিপ = ফাংশনস HTTP.onRequest (স্ট্রাইপ) লাগে;
OK200

@ Ok200 আপনি ফায়ারবেস কমান্ড লাইনের সাথে কমান্ডটি ব্যবহার করছেন? আপনাকে সহায়তা করতে, আমাকে কিছু কোড দেখতে হবে
আজোরকেরা

3

দীর্ঘ মেয়াদে আপনার সমস্ত মেঘের ক্রিয়াকলাপকে সংগঠিত করার জন্য খুব সুন্দর উপায় রয়েছে। আমি সম্প্রতি এটি করেছি এবং এটি নির্দ্বিধায় কাজ করছে।

আমি যা করেছি তা হ'ল প্রতিটি মেঘ ফাংশন তাদের ট্রিগার শেষের পয়েন্টের ভিত্তিতে পৃথক ফোল্ডারে সংগঠিত করেছিল was প্রতিটি ক্লাউড ফাংশন ফাইলের নাম দিয়ে শেষ হয় *.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
এই পদ্ধতির সত্যিই দুর্দান্ত। আমি ভাবছিলাম যে ফাংশন নামগুলিতে স্ল্যাশগুলির অনুমতি দেওয়ার জন্য সামঞ্জস্য করা সম্ভব হয় যাতে আপনি বিভিন্ন এপিআই সংস্করণগুলি পৃথক করতে পারেন, উদাহরণস্বরূপ (এপিআই ভি 1, এপিআই ভি 2, ইত্যাদি)
অ্যালেক্স সোরোকোলেটোভ

আপনি কেন একই প্রকল্পের আওতায় মেঘের বিভিন্ন সংস্করণ রাখতে চান? যদিও আপনি এটি করতে পারেন ডিরেক্টরি কাঠামোর সামান্য পরিবর্তন করে, ডিফল্ট সূচক অনুসারে সমস্ত মেঘ ফাংশন মোতায়েন করবে আপনি যদি নির্বাচিতভাবে স্থাপন না করেন বা আপনার সূচি.জেজে যদি-শর্তগুলি ব্যবহার না করেন যা শেষ পর্যন্ত আপনার কোডের
বিশৃঙ্খলা

1
আমি সমস্ত কিছু মোতায়েন করার সাথে ঠিক আছি, আমি যে ফাংশনগুলি রেখেছি তার কেবল সংস্করণ করতে চাই (
এইচটিপিটি ট্রিগারযুক্তগুলি

আমি প্রত্যাশা করছি যে প্রতিটি HTTP ট্রিগার তার নিজস্ব *.f.jsফাইলে রয়েছে। কমপক্ষে আপনি যা করতে পারেন তা প্রতিটি সংস্করণের জন্য ফাইলটির নাম পরিবর্তন করে এটির মতো *.v1.f.jsবা অন্য কিছু তৈরি করার জন্য প্রত্যয়টি প্রেরণ করে *.v2.f.js(আপনার সমস্ত HTTP ট্রিগারের সমস্ত সংস্করণটি লাইভ বলে ধরে নিচ্ছেন )। আপনার আরও ভাল সমাধান থাকলে দয়া করে আমাকে জানান।
ক্রিতেশ

1

আমি ব্যবহার করতে চাই সমস্ত ফাংশন স্বয়ংক্রিয়ভাবে অন্তর্ভুক্ত করতে আমি একটি ভ্যানিলা জেএস বুটলোডার ব্যবহার করি।

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

এই উদাহরণটি সূচি.জেএস ফাইল কেবল রুটের মধ্যে ডিরেক্টরিগুলি স্বয়ংক্রিয়ভাবে অন্তর্ভুক্ত করে। এটি হাঁটা ডিরেক্টরি, সম্মান .gitignore ইত্যাদিতে প্রসারিত হতে পারে যদিও এটি আমার পক্ষে যথেষ্ট ছিল।

সূচী ফাইলটি স্থানে থাকাতে নতুন ফাংশন যুক্ত করা তুচ্ছ।

/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

এই ওয়ার্কফ্লোটি কেবলমাত্র "লেখুন এবং চালান", ইনডেক্স.জেএস ফাইলটি প্রতিবার কোনও নতুন ফাংশন / ফাইল যুক্ত / সংশোধন / সরানো না করেই পরিবর্তন করতে হবে।


এই ঠান্ডা শুরু হবে না?
আইয়্প্পা

1

আপনি টাইপ স্ক্রিপ্ট সহ ক্লাউড ফাংশন তৈরি করে থাকলে এখানে একটি সহজ উত্তর's

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

শীর্ষে আপনার নিয়মিত আমদানিগুলির কাছাকাছি থেকে সমস্ত ফাংশন রফতানি করুন foo.ts

export * from './foo';


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.