0

I tried everything , I have this cloud function (that otherwise works) :

     exports.contentServer = functions.https.onRequest((request, response) => {
          admin.database().ref('/list/' + "abc").once('value').then(function(snapshot) {
              console.log(snapshot.val() );
              return null;
              }).catch(function(error) {
                  console.log("Error getting document:", error);
                  return response.send(error);
              });

 });

or also this :

     admin.database().ref('/list').once('value').then(function(snapshot) {
        var event = snapshot.val();   
        app.tell('Result: '+event);
   });

and this :

     exports.contentServer = functions.https.onRequest((request, response) => {


          var db = admin.database();


            db.ref("list/abc").once("value").then(snap => {
              var store = snap.val().description;
              return store;
            }).then(() => {
              var store = snap.val().description;
              return store;
            }).then(snap => {
              var store = snap.val().description;
              return store;
            }).catch(err => {
              console.log(err);
              response.send("error occurred");
            });

 });

and always get back the error :

"Could not handle the request"

Or I get error on deploy that :

 Each then() should return a value or throw 

I have a collection called list, inside I have a document named "abc".

Is there something I have to include ? something I have to setup in Firebase to make it work ? anything basic nobody write on the docs ?

Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121
Curnelious
  • 1
  • 16
  • 76
  • 150
  • You may be interested by the 3 videos about "JavaScript Promises" from the Firebase video series: https://firebase.google.com/docs/functions/video-series/ – Renaud Tarnec May 03 '19 at 13:45

2 Answers2

2

Modified following the comments above explaining the OP uses Firestore and not the Realtime Database

You should do as follows. You have to wait that the promise returned by the get() method resolves before sending back the response. For this you need to use the then() method, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then

 exports.contentServer = functions.https.onRequest((request, response) => {
      admin.firestore().collection('list').doc('abc').get()
      .then(docSnapshot => {
          console.log(docSnapshot.data());
          return response.send(docSnapshot.data()); // or any other value, like return response.send( {result: "success"} );
      })
      .catch(error => {
          console.log("Error getting document:", error);
          return response.status(500).send(error); 
      });
});

As written in the comments above, I would suggest that you watch the 3 videos about "JavaScript Promises" from the Firebase video series: https://firebase.google.com/docs/functions/video-series/

Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121
  • Your answer really solved the problem. thank you so much. I have low votes so I can't even upvote you, instead I wish you have the best weekend you had for a while. ;) – Curnelious May 04 '19 at 01:03
  • 1
    @condalism Happy that I could help! At the time of writing I see that you do have the necessary points to upvote my answer. Please do so if it was helpful. And I wish you a nice WE too!! – Renaud Tarnec May 04 '19 at 06:34
  • I did. btw I have a problem with your code now, a really strange problem - it will execute a function multiple times, and I can't find a solution , can you please take a look ? https://stackoverflow.com/questions/55979565/firebase-function-is-being-executed-multiple-times – Curnelious May 04 '19 at 07:05
0

Try this

Updated. Return the response inside then() as what @Renaud Tarnec pointed out.

Using realtime database

exports.contentServer = functions.https.onRequest((request, response) => {
     var database = admin.database();
     database.ref('list').child('abc').once("value", snapshot => {
         const data = snapshot.val();
         return response.send(data);
     }).catch(error => {
         return response.status(500).send(error); 
     });
});

If you are using firestore.

exports.contentServer = functions.https.onRequest((request, response) => {
     const firestore = admin.firestore();
     firestore.collection("list").doc('abc').get().then(doc => {
         console.log(doc.data());
         return response.send(doc.data());
     }).catch(error => {
         return response.status(500).send(error);
     });
});

Important: Don't forget to terminate the request by calling response.redirect(), response.send(), or responses.end() so you can avoid excessive charges from functions that run for too long

elbert rivas
  • 1,464
  • 1
  • 17
  • 15
  • Error: could not handle the request. I have a feeling that something really strange is going on. I can not even log things anymore to the console. What could be happening here ? – Curnelious May 03 '19 at 13:13
  • Are you using spark plan? Perhaps you have reached the qouta. @condalism – elbert rivas May 03 '19 at 13:15
  • I can see on the log that it loges some text, I can see that function excuted started, then I see it ended, then after a while I see Null, which means i guess he printed null in the call to DB. so my DB has a collection named list, then inside there is one document called abc, but for some reason it wouldn't find it. (your code include once() twice so I removed one of them) . it just won't read the DB from a function. – Curnelious May 03 '19 at 13:59
  • "Function execution took 11 ms, finished with status code: 200", it takes him 10 seconds to get a return from the db function and then he prints null. – Curnelious May 03 '19 at 14:03
  • Please add your db structure in your question @condalism – elbert rivas May 03 '19 at 14:04
  • And by the way, are you using firestore or realtime db. You mentioned collection and document. @condalism – elbert rivas May 03 '19 at 14:11
  • It's just a collection called "list", then inside many documents, one of them called "abc" (its document ID is abc), and that's it, I need to read its content. – Curnelious May 03 '19 at 14:11
  • Are you using firestore? @condalism – elbert rivas May 03 '19 at 14:15
  • Yes I use firestore....Is this way for real time db ? how its done with firestore ? – Curnelious May 03 '19 at 14:18
  • Thanks it works ! but it takes 60000ms (one minute!) to finish this function, why ? Function execution took 60002 ms, finished with status: 'timeout' – Curnelious May 03 '19 at 14:28
  • Firestore cold start. You can read [this](https://stackoverflow.com/questions/46717898/firestore-slow-performance-issue-on-getting-data#46750456) for details. – elbert rivas May 03 '19 at 14:32
  • Thanks a lot ! so just wait for a while to get better ? do I have to close the connection somehow ? what if I want to return a certain page after the function finish? how its being done ? thanks elbert you helped me a lot ! – Curnelious May 03 '19 at 14:42
  • @condalism & @elbertrivas If I may, in the two examples above the response is sent back before the asynchronous queries are completed. You have to send the response back within the `then()`, see my answer. You will see that the Cloud Function will execute much faster than 1 minute. – Renaud Tarnec May 03 '19 at 14:46
  • 1
    @RenaudTarnec makes sense. Thanks. – elbert rivas May 03 '19 at 15:15