How to Retrieve individual JSON values from Firebase Database? - javascript

Let's say I have a firebase node that is dbref = firebase.ref('/Transfer_Request/{pushID]/').
And the client writes two values; from_ID and to_ID to dbref. How do I get the individual values of the from_ID and to_ID from Firebase Cloud functions?
My code:
exports.TransferTicket = functions.database.ref('/Transfer_Request/{pushID}').onWrite((event) => {
const original = event.data.val();
const from_ID = original.from_ID;
const to_email_ID = original.to_ID;
//search for to_email ID
return admin.database().set("A transfer request was just made");
});
I'm getting two errors:
1)
TypeError: admin.database(...).set is not a function at
exports.TransferTicket.functions.database.ref.onWrite
(/user_code/index.js:41:25) at Object.
(/user_code/node_modules/firebase-functions/lib/cloud-functions.js:59:27)
at next (native) at
/user_code/node_modules/firebase-functions/lib/cloud-functions.js:28:71
at __awaiter
(/user_code/node_modules/firebase-functions/lib/cloud-functions.js:24:12)
at cloudFunction
(/user_code/node_modules/firebase-functions/lib/cloud-functions.js:53:36)
at /var/tmp/worker/worker.js:716:24 at process._tickDomainCallback
(internal/process/next_tick.js:135:7)
2)
TypeError: Cannot read property 'from' of null at
exports.TransferTicket.functions.database.ref.onWrite
(/user_code/index.js:35:25) at Object.
(/user_code/node_modules/firebase-functions/lib/cloud-functions.js:59:27)
at next (native) at
/user_code/node_modules/firebase-functions/lib/cloud-functions.js:28:71
at __awaiter
(/user_code/node_modules/firebase-functions/lib/cloud-functions.js:24:12)
at cloudFunction
(/user_code/node_modules/firebase-functions/lib/cloud-functions.js:53:36)
at /var/tmp/worker/worker.js:716:24 at process._tickDomainCallback
(internal/process/next_tick.js:135:7)

The first problem comes from the fact that when doing the following you miss a Firebase Reference.
return admin.database().set("A transfer request was just made");
You should do:
admin.database().ref('...the path where you want to write...').set("A transfer request was just made");
For more details, see the doc for Reference and Database .
The second problem comes from the fact that since the new release of the version 1.0.0 of the Firebase SDK for Cloud Functions, the syntax has changed. See this doc item.
You should modify your code as follows:
exports.TransferTicket = functions.database.ref('/Transfer_Request/{pushID}').onWrite((change, context) => {
const original = change.after.val();
const from_ID = original.from_ID;
console.log(from_ID);
const to_email_ID = original.to_ID;
console.log(to_email_ID);
return admin.database().ref('...path...').set("A transfer request was just made")
.catch(error => {
console.log(error);
//...
});
});

Related

Passing in list elements in javascript to a different function

I'm trying to do a web scraping exercise where some values are being retrieved and are being stored in a list variable. I am then passing in the list variable as a parameter in a different function. The problem with my approach is I am getting an error when calling the different function. I believe I'm getting this error because I am not passing in the list elements into the function appropriately. In the function, I am reading from a Yahoo Stock API used to retrieve stock data. If I were to hardcode a stock symbol into the parameter for the function, it works without any issue. Since I am passing in a parameter, I am getting this error. Below is my code and the error I am getting. Any feedback would be helpful.
Code
const cheerio = require('cheerio');
const axios = require('axios');
const yahooStockPrices = require('yahoo-stock-prices');
var stockSymbol = []
async function read_fortune_500() {
try {
const { data } = await axios({ method: "GET", url: "https://en.wikipedia.org/wiki/List_of_S%26P_500_companies", })
const $ = cheerio.load(data)
const elemSelector = '#constituents > tbody > tr > td:nth-child(1)'
$(elemSelector).each((parentIndex, parentElem) => {
let keyIndex = 0
if (parentIndex <= 9){
$(parentElem).children().each((childIndex, childElem) => {
const tdValue = $(childElem).text()
if (tdValue) {
//stockObject[keys[keyIndex]] = tdValue
stockSymbol = tdValue
}
})
console.log(stockSymbol)
}
})
} catch (err) {
console.error(err)
}
return stockSymbol;
}
async function collect_stocks(stockSymbol) {
stockSymbol = read_fortune_500()
const stockResult = await yahooStockPrices.getCurrentData(stockSymbol);
console.log(stockResult);
}
collect_stocks(stockSymbol)
Error
/node_modules/yahoo-stock-prices/yahoo-stock-prices.js:75
.split('regularMarketPrice')[1]
^
TypeError: Cannot read properties of undefined (reading 'split')
at Request._callback (/node_modules/yahoo-stock-prices/yahoo-stock-prices.js:75:21)
at Request.self.callback (/node_modules/request/request.js:185:22)
at Request.emit (node:events:390:28)
at Request.emit (node:domain:475:12)
at Request.<anonymous> (/node_modules/request/request.js:1154:10)
at Request.emit (node:events:390:28)
at Request.emit (node:domain:475:12)
at IncomingMessage.<anonymous> (/node_modules/request/request.js:1076:12)
at Object.onceWrapper (node:events:509:28)
at IncomingMessage.emit (node:events:402:35)
The parameter stockSymbol seems to be empty when you pass it to your desired function therefore, when yahoo-stock-prices try to apply a split on it, it fails.

How to solve сannot read property 'databaseURL' of null in Cloud Functions for Firebase?

I have a table titled 'bestOffers' in Cloud Firestore
I am using a function that calls when a document is added to a table.
The event settings are like this:
Event type: create
The path to the document: bestOffers/{id}
Function:
And when I run the function, I get a cannot read property 'databaseURL' of null error
Can you please tell me what am I doing wrong?
Code:
const functions = require('firebase-functions')
const admin = require('firebase-admin')
admin.initializeApp()
exports.sendNotification = functions.database.ref('bestOffers/{id}').onWrite(async (change, context) => {
})
Tracing:
TypeError: Cannot read property 'databaseURL' of null
at resourceGetter (/workspace/node_modules/firebase-functions/lib/providers/database.js:92:54)
at cloudFunctionNewSignature (/workspace/node_modules/firebase-functions/lib/cloud-functions.js:102:13)
at cloudFunction (/workspace/node_modules/firebase-functions/lib/cloud-functions.js:151:20)
at Promise.resolve.then (/layers/google.nodejs.functions-framework/functions-framework/node_modules/#google-cloud/functions-framework/build/src/invoker.js:198:28)
at process._tickCallback (internal/process/next_tick.js:68:7)
Have a look at the signature of the handler function that is passed to onWrite. It has two parameters: a Change<DataSnapshot> and an EventContext.
You declare your Cloud Function with:
...onWrite(async () => {...});
You should do as follows:
.onWrite(async (change, context) => {
const beforeData = change.before.val(); // data before the write
const afterData = change.after.val(); // data after the write
});
and, then, use the change object to get the data stored at the node that triggered the Cloud Function.

Calling async method from instanced Object gives error: TypeError: Object(...) is not a function

I am currently developing an app for educational purposes and facing a problem that is probably trivial but can't get around and solve it.
So basically I am trying to fetch some data from an external API (using Axios for that). I have divided my code into modules that I am exporting to index.js file and from that, I am instancing new Object and calling my async method getResults() which in return should give me data from API. From that point a get error
TypeError: Object(...) is not a function.
Here is an example code:
Module Search.js:
export default class Search {
constructor(query, num) {
this.query = query;
this.num = num;
}
async getResults() {
const url = 'API_URL';
const key = 'API_KEY';
try {
const res = await axios(`${url}?query=${this.query}&number=${this.num}&apiKey=${key}`);
this.result = res.data.results;
console.log(this.result);
} catch (error) {
console.log(error);
}
}
}
And here is index.js file:
import Search from "./models/Search";
const s = new Search('cheese', 2);
s.getResults()
And finally error in console:
TypeError: Object(...) is not a function
at Search._callee$ (Search.js:42)
at tryCatch (runtime.js:65)
at Generator.invoke [as _invoke] (runtime.js:303)
at Generator.prototype.<computed> [as next] (runtime.js:117)
at asyncGeneratorStep (Search.js:5)
at _next (Search.js:7)
at eval (Search.js:7)
at new Promise (<anonymous>)
at Search.eval (Search.js:7)
at Search.getResults (Search.js:65)
I am probably doing something wrong here, any help and insight would be appreciated. Thanks.
await axios(`${url}?query=${this.query}&number=${this.num}&apiKey=${key}`);
This is the line creating error,
axios is an object which you are trying to use as function
You probably wish to use get/post method provided by axios to call your endpoint
await axios.get(`${url}?query=${this.query}&number=${this.num}&apiKey=${key}`);
You can have a look how you want to use axios https://github.com/axios/axios

Cloud Firestore: TypeError: Cannot read property 'ref' of undefined

Cloud Firestore: TypeError: Cannot read property 'ref' of undefined
I'm using Cloud Functions to update the comments number in the parent collection of Cloud Firestore, so when a comment added the Cloud Functions can automatically update the comment number.
exports.updateCommentNumbers = functions.firestore
.document('postlist/{postlistId}/comments/{commentsID}')
.onCreate(event =>
{
const collectionRef = event.after.ref.parent;
const countRef = collectionRef.parent.child('comment_number');
//const previousValue = event.data.previous.data();
let increment;
if (event.after.exists() )
{
increment = 1;
}
else
{
return null;
}
return countRef.transaction((current) =>
{
return (current || 0) + increment;
}).then(() =>
{
return console.log('Comments numbers updated.');
});
});
I got error which I don't understand. Could you tell me what's wrong?
TypeError: Cannot read property 'ref' of undefined
at exports.updateCommentNumbers.functions.firestore.document.onCreate.event
(/user_code/index.js:46:35)
at Object. (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:112:27)
at next (native)
at /user_code/node_modules/firebase-functions/lib/cloud-functions.js:28:71
at __awaiter (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:24:12)
at cloudFunction (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:82:36)
at /var/tmp/worker/worker.js:716:24
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
As show in this upgrade guide the signature of Cloud Functions for Firebase has changes when it switched to v1.0.
If you used this before v1.0:
exports.dbWrite = functions.firestore.document('/path').onWrite((event) => {
const beforeData = event.data.previous.data(); // data before the write
const afterData = event.data.data(); // data after the write
});
It now is:
exports.dbWrite = functions.firestore.document('/path').onWrite((change, context) => {
const beforeData = change.before.data(); // data before the write
const afterData = change.after.data(); // data after the write
});
Instead of rewriting the code for you, I recommend you update it based on that documentation, or check where you got the code from to see if there's an updated version.

Cloud Messaging in Cloud Functions: admin.messagin(...).send is not a function

My function is triggered by a database event and uses Firebase Cloud Messaging to send a notification to a topic. My first function works fine, but the second one keeps throwing this error:
2018-02-20T21:16:49.878Z E receiveMessage: TypeError: admin.messaging(...).send is not a function
at exports.receiveMessage.functions.database.ref.onCreate (/user_code/index.js:55:27)
at Object.<anonymous> (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:59:27)
at next (native)
at /user_code/node_modules/firebase-functions/lib/cloud-functions.js:28:71
at __awaiter (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:24:12)
at cloudFunction (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:53:36)
at /var/tmp/worker/worker.js:695:26
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
here is the index.js file:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
// // Create and Deploy Your First Cloud Functions
// // https://firebase.google.com/docs/functions/write-firebase-functions
//
// exports.helloWorld = functions.https.onRequest((request, response) => {
// response.send("Hello from Firebase!");
// });
exports.recceiveInvitation = /* the function that works */;
exports.receiveMessage = functions.database.ref('/messages/{chatId}/{time}').onCreate((event) => {
const chatId = event.params.chatId;
console.log('messages', chatId);
var sender = event.data.val().name;
var messageContent = event.data.val().message;
if(messageContent.length >= 100){
messageContent = messageContent.substring(0,97)+"...";
}
const payload = {
data: {
title: `New Message from ${sender}`,
body: messageContent
},
topic: chatId
};
return admin.messaging().send(payload);
});
I ran npm install firebase-admin, but I did not help.
change this:
return admin.messaging().send(payload);
to this:
return admin.messaging().sendToTopic(topicname,payload);
to be able to send notifications to topics.
You can do the above, or check the note below
Note:
You need to update the firebase-admin npm package, to be able to use send():
npm install firebase-admin#latest
more info here:-
https://firebase.google.com/support/release-notes/admin/node
https://firebase.google.com/docs/cloud-messaging/admin/send-messages
let message = {notification: {title: "your title",body: "your message",},token:"token of user device"
};
admin.messaging().send(message)

Categories

Resources