When connect firebase to node project it show db is not defined.
Progress.js
const Progress = require("../models/progress");
//add new Progress
exports.addProgress = async (req, res) => {
//constant variables for the attributes
const {name, description, type, date,imgUrl} = req.body;
//object
const newProgress= new Progress({
//initializing properties
name,
description,
type,
date,
imgUrl
})
//saving the object to the db
newProgress.save().then(() => {
res.status(200).json({ status: "New Progress Added" });
}).catch((error) => {
res.status(500).json({message:"Fail to Progress Item",error:error.message})
})
}
model
I think you missed to initialize DB, Try This -
const firestore = require("firebase-admin");
const db = firestore.firestore();
Related
I am building out the backend for a flash card app for which you can find the repo here. There is a table called categories. There is an endpoint for adding a category.
router.post("/", protect, createCategory);
The endpoint runs a createCategory function which has logic separated out into a categoryController.js file.
const Categories = require("../models/categoryModel");
const createCategory = async (req, res) => {
const { title } = req.body;
const userId = req.user.id;
if (!title) {
res.status(404).json({ errMsg: "Please provide a title" });
} else {
const category = await Categories.createCategory({ title, userId });
console.log("category: ", category);
res.status(201).json(category);
}
};
The createCategory controller function in turn calls a createCategory function from the categoryModel.js file. The function from the model runs the database operations. Specifically, it inserts a new category into the database and references another function--getCategoryById--to return the newly created category.
const getCategoryById = (id) => {
return db("categories").where({ id }).first();
};
const createCategory = (category) => {
return db("categories")
.insert(category, "id")
.then((ids) => {
const [id] = ids;
return getCategoryById(id);
});
};
The problem is when I make the .post to create a new category, nothing is returned in the response. The database gets updated just fine but nothing is returned. You can see that I put a console.log in the controller and that is coming back undefined. I am not sure why.
I am trying to pass createdBy and updatedBy information to every query with mongoose. Is there any way to do this using middlewares with express and/or Apollo Graphql?
I then will use mongoose.set to send debug information to our logging server.
I managed to solve this using AsyncLocalStorage implementation.
this is my threadContext implementation
const { AsyncLocalStorage } = require('async_hooks');
const localStorage = new AsyncLocalStorage();
const contextInit = {
user: null,
environment: process.env.DEPLOYMENT_ENV || 'local',
sourceCompany: undefined,
};
const getContext = () => localStorage.getStore();
const initializeContext = (additionalContext) => localStorage.enterWith({ ...contextInit, ...additionalContext });
const updateContext = (context) => {
Object.keys(context).forEach((k) => {
localStorage.getStore()[k] = context[k];
});
};
module.exports = {
getContext,
contextInit,
initializeContext,
updateContext,
};
then, I injected middleware to initialize the context to express
const { initializeContext: initializeThreadContext } = require('./services/threadContext');
const RequestId = require('./helpers/expressRequestId');
app.use(RequestId()); <<-- feel free to write your own
app.use((req, res, next) => {
initializeThreadContext({ requestId: req.id });
next();
});
In apollo server context to store user data
// include user in threadContext
threadContext.getContext().user = user ? { _id: user._id, name: user.name } : undefined;
then in mongoose, I am logging our queries with user data
mongoose.set('debug', (collectionName, methodName, query, doc, ...methodArgs) => {
const ignoredMethods = [/createIndex/, /watch/];
if (ignoredMethods.some((m) => new RegExp(m).test(methodName))) return;
logger.debug(`Mongodb operation '${methodName}' on '${collectionName}'`, {
collectionName,
methodName,
query,
...threadContext.getContext(),
});
});
I preferred not to store user info with createdBy instead logged it
I just typed a code in my index.js file of functions (firebase CLI).According to my code there must be a timeline collection created in cloud database of firebase.Function is healthy and there are no errors it gets deployed and even in the logs everything works fine. But still timeline collection is not created in the cloud databaese when I follow a user in my app.
this is my code:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
exports.onCreateFollower = functions.firestore
.document("/followers/{userId}/userFollowers/{followerId}")
.onCreate(async (snapshot, context) => {
console.log("Follower Created", snapshot.id);
const userId = context.params.userId;
const followerId = context.params.followerId;
// 1) Create followed users posts ref
const followedUserPostsRef = admin
.firestore()
.collection("posts")
.doc(userId)
.collection("userPosts");
// 2) Create following user's timeline ref
const timelinePostsRef = admin
.firestore()
.collection("timeline")
.doc(followerId)
.collection("timelinePosts");
// 3) Get followed users posts
const querySnapshot = await followedUserPostsRef.get();
// 4) Add each user post to following user's timeline
querySnapshot.forEach(doc => {
if (doc.exists) {
const postId = doc.id;
const postData = doc.data();
return timelinePostsRef.doc(postId).set(postData);
}
});
});
Since you want to execute a variable number of asynchronous calls in parallel, you should use Promise.all(), in order to wait that all these different asynchronous calls are completed before indicating to the CF platform that it can cleanup the CF. See https://firebase.google.com/docs/functions/terminate-functions for more details.
exports.onCreateFollower = functions.firestore
.document("/followers/{userId}/userFollowers/{followerId}")
.onCreate(async (snapshot, context) => {
const userId = context.params.userId;
const followerId = context.params.followerId;
// ...
// 3) Get followed users posts
const querySnapshot = await followedUserPostsRef.get();
// 4) Add each user post to following user's timeline
const promises = [];
querySnapshot.forEach(doc => {
//query results contain only existing documents, the exists property will always be true and data() will never return 'undefined'.
const postId = doc.id;
const postData = doc.data();
promises.push(timelinePostsRef.doc(postId).set(postData));
});
return Promise.all(promises);
});
I have used the code from the Firebase documentation to schedule a backup of the data in my Firestore project in a bucket every 6 hours. See the link and the code here:
https://firebase.google.com/docs/firestore/solutions/schedule-export
const functions = require('firebase-functions');
const firestore = require('#google-cloud/firestore');
const client = new firestore.v1.FirestoreAdminClient();
// Replace BUCKET_NAME
const bucket = 'gs://BUCKET_NAME';
exports.scheduledFirestoreExport = functions.pubsub
.schedule('every 24 hours')
.onRun((context) => {
const projectId = process.env.GCP_PROJECT || process.env.GCLOUD_PROJECT;
const databaseName =
client.databasePath(projectId, '(default)');
return client.exportDocuments({
name: databaseName,
outputUriPrefix: bucket,
// Leave collectionIds empty to export all collections
// or set to a list of collection IDs to export,
// collectionIds: ['users', 'posts']
collectionIds: []
})
.then(responses => {
const response = responses[0];
console.log(`Operation Name: ${response['name']}`);
})
.catch(err => {
console.error(err);
throw new Error('Export operation failed');
});
});
Everything works well, my data is saved like I want to but nevertheless I am getting an error:
Error serializing return value: TypeError: Converting circular structure to JSON
Can someone tell me what I should change? Would be glad to get a hint.
I have a question for dialogflow. I want to know if it's possible to have the agent create new fields or tables in the firebase database (firestore or realtime) All the code I find is about changing the values of a table and not creating them.
I do not know where to start, I've done integrations with the server and everything is working.
function writeToDb (agent) {
const databaseEntry = agent.parameters.databaseEntry;
const dialogflowAgentRef = db.collection('dialogflow').doc('agent');
return db.runTransaction(t => {
t.set(dialogflowAgentRef, {entry: databaseEntry});
return Promise.resolve('Write complete');
I need a explication to create new tables or fields by the agent
Google's Dialogflow Firestore sample on Github demonstrates how to connect Dialogflow to the Firestore database.
Check out the writeToDb() function below, and remember to require the same dependencies:
'use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const {WebhookClient} = require('dialogflow-fulfillment');
process.env.DEBUG = 'dialogflow:*'; // enables lib debugging statements
admin.initializeApp(functions.config().firebase);
const db = admin.firestore();
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
function writeToDb (agent) {
// Get parameter from Dialogflow with the string to add to the database
const databaseEntry = agent.parameters.databaseEntry;
// Get the database collection 'dialogflow' and document 'agent' and store
// the document {entry: "<value of database entry>"} in the 'agent' document
const dialogflowAgentRef = db.collection('dialogflow').doc('agent');
return db.runTransaction(t => {
t.set(dialogflowAgentRef, {entry: databaseEntry});
return Promise.resolve('Write complete');
}).then(doc => {
agent.add(`Wrote "${databaseEntry}" to the Firestore database.`);
}).catch(err => {
console.log(`Error writing to Firestore: ${err}`);
agent.add(`Failed to write "${databaseEntry}" to the Firestore database.`);
});
}
function readFromDb (agent) {
// Get the database collection 'dialogflow' and document 'agent'
const dialogflowAgentDoc = db.collection('dialogflow').doc('agent');
// Get the value of 'entry' in the document and send it to the user
return dialogflowAgentDoc.get()
.then(doc => {
if (!doc.exists) {
agent.add('No data found in the database!');
} else {
agent.add(doc.data().entry);
}
return Promise.resolve('Read complete');
}).catch(() => {
agent.add('Error reading entry from the Firestore database.');
agent.add('Please add a entry to the database first by saying, "Write <your phrase> to the database"');
});
}
// Map from Dialogflow intent names to functions to be run when the intent is matched
let intentMap = new Map();
intentMap.set('ReadFromFirestore', readFromDb);
intentMap.set('WriteToFirestore', writeToDb);
agent.handleRequest(intentMap);
});