I would like to connect to my Atlas cluster only once per instance running Cloud Functions.
Here is my code for an instance :
const MongoClient = require("mongodb").MongoClient; const client = new MongoClient("myUrl", { useNewUrlParser: true, useUnifiedTopology: true, }); exports.myHttpMethod = functions.region("europe-west1").runWith({ memory: "128MB", timeoutSeconds: 20, }).https.onCall((data, context) => { console.log("Data is: ", data); client.connect(() => { const testCollection = client.db("myDB").collection("test"); testCollection.insertOne(data); }); });
And i would like to avoid the client.connect()
in each function call that seems to be really too much.
I would like to do something like this :
const MongoClient = require("mongodb").MongoClient; const client = await MongoClient.connect("myUrl", { useNewUrlParser: true, useUnifiedTopology: true, }); const db = client.db("myDB"); exports.myHttpMethod = functions.region("europe-west1").runWith({ memory: "128MB", timeoutSeconds: 20, }).https.onCall((data, context) => { console.log("Data is: ", data); const testCollection = db.collection("test"); testCollection.insertOne(data); });
But i can’t await
like this.
In my AWS Lambda functions (running in python) i have not this issue and i am able to connect only once per instance, so i guess there is an equivalent but i don’t know much JS / Node JS.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
You can store your database client as a global variable. From the documentation,
Cloud Functions often recycles the execution environment of a previous invocation. If you declare a variable in global scope, its value can be reused in subsequent invocations without having to be recomputed.
Try refactoring the code as shown below:
import * as functions from "firebase-functions"; import { MongoClient } from "mongodb"; let client: MongoClient | null; const getClient = async () => { if (!client) { const mClient = new MongoClient("[MONGODB_URI]", {}); client = await mClient.connect(); functions.logger.log("Connected to MongoDB"); } else { functions.logger.log("Using existing MongoDB connection"); } functions.logger.log("Returning client"); return client; }; export const helloWorld = functions.https.onRequest( async (request, response) => { const db = (await getClient()).db("[DATABASE]"); const result = await db.collection("[COLLECTION]").findOne({}); response.send("Hello from Firebase!"); } );
This should reuse the connection for that instance.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0