0

I am trying to set up cloud functions with firebase and I am having a slightly difficult time getting it set up. I want to set up a function that gets called by an HTTP request. The function would take the information provided, double-check if those values are indeed the same values as the ones found in my firestorm and then execute some Javascript code before responding; this is my code:

// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers. const functions = require("firebase-functions"); // The Firebase Admin SDK to access Firestore. const admin = require('firebase-admin'); admin.initializeApp(); // [START trigger] exports.buyCrypto = functions.https.onRequest((request, res) => { // [END trigger] // [START sendError] // Forbidding PUT requests. if (request.method === 'PUT') { return res.status(403).send('Forbidden!'); } // [END sendError] // [START readQueryParam] const uid = request.body.uid const crypto = request.body.crypto const amount = request.body.amount const docRef = admin.firestore().collection("users").doc(uid); docRef.get().then((doc) => { if (doc.exists) { if(crypto === "BTC") { if(doc.data.btc <= amount) { //execute buy return res.status(200).send("Sucess"); } } if(crypto === "ETH") { if(doc.data.btc <= amount) { //execute buy return res.status(200).send("Sucess"); } } } else { // doc.data() will be undefined in this case console.log("No such document!"); } }).catch((error) => { console.log("Error getting document:", error); }); // Push the new message into Firestore using the Firebase Admin SDK. //const writeResult = await admin.firestore().collection('messages').add({original: original}); // Send back a message that we've successfully written the message // [START sendResponse] const formattedResponse = "IDK" return res.status(403).send("Failed"); // [END sendResponse] }); 

Unfortunatly I cannot seem to find a great deal of documentation for firebase functions and when I try to test it with the emulator through a web browser it goes into infinite loading and does not display an error message so I am finding it impossible to debug anything. Thank you for your time

1 Answer 1

1

You are calling return res.status(403).send("Failed"); outside of the then() block, so this line will be called before the asynchronous call to the get() method is completed and the Promise returned by this method is fulfilled. Result: your Cloud Function always sends back an error to its caller.

In addition, you do doc.data.btc instead of doc.data().btc. See the doc for the DocumentSnapshot, data() is a method.

Also, note that you don't need to use return in an HTTPS Cloud Function. Just send back a response with res.redirect(), res.send(), or res.end(). You may watch this video: https://www.youtube.com/watch?v=7IkUgCLr5oA.

The following should therefore do the trick:

exports.buyCrypto = functions.https.onRequest((request, res) => { if (request.method === 'PUT') { return res.status(403).send('Forbidden!'); } const uid = request.body.uid const crypto = request.body.crypto const amount = request.body.amount const docRef = admin.firestore().collection("users").doc(uid); docRef.get().then((doc) => { if (doc.exists) { if (crypto === "BTC") { if (doc.data().btc <= amount) { //execute buy res.status(200).send("Success"); } else { // send a 200 response or throw an error res.status(200).send("...."); // Depends on your functional requirements } } else if (crypto === "ETH") { if (doc.data.btc <= amount) { //execute buy return res.status(200).send("Success"); } else { // send a 200 response or throw an error res.status(200).send("...."); // Depends on your functional requirements } } else { // send a 200 response or throw an error res.status(200).send("...."); // Depends on your functional requirements } } else { console.log("No such document!"); // send a 200 response or throw an error res.status(200).send("...."); } }).catch((error) => { console.log("Error getting document:", error); res.status(500).send(error); }); }); 
Sign up to request clarification or add additional context in comments.

7 Comments

thank you for your comment, I watched the video and it makes more sense now how HTTPS functions work. I only have one problem, I tried this approach and also the one from the video "const promise = admin.firestore().doc(dataPath).get();" with datapath = 'users/'+uid but unfortunatly it cannot find the document I need. I double checked my firestore, I have a users collection with documents names after the uid and it cannot find anything, is there some configuration that needs to be done for the admin.firestore object?
You should not have any problem with your code. You correctly do const admin = require('firebase-admin'); admin.initializeApp(); and your query syntax is correct. Are you sure uid Has the correct value? What do you see if you do console.log(uid);?
gyazo.com/1f499b6da4836bc150391bf2420543f6 Here is a screenshot of all the info. On the left, I have my fire store data with users collection and the documents. On the left, I have the nodeJS terminal with the execution. I wrote a few console logs of the information that is sent to the function, I pull it out of the request body and print it and it seems all the information is there.
What happens if you deploy your function and run it without the emulator (calling the "real" endpoint, hosted on Firebase/GCP platform).
Actually, that is a good point, I never attempted it before. I am still on the free plan so I cannot deploy to a real endpoint until I upgrade to a pay as you go, model. So far I am only testing cloud functions with an app that might not go public. Would there be a difference between the emulator and the real endpoint?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.