0

I have seen this question asked, but with no good answer. I can understand what the issue is, but can't seem to find out how to remedy it. Here is my function:

//set JSON content type and CORS headers for the response
response.header('Content-Type','application/json');
response.header('Access-Control-Allow-Origin', '*');
response.header('Access-Control-Allow-Headers', '*');

//respond to CORS preflight requests
if (request.method == 'OPTIONS') {
response.status(204).send('');
}

// pull in firebase
var firebase = require('firebase');

require("firebase/firestore");

let config = {
  // config stuff here
}

if (!firebase.apps.length) {
firebase.initializeApp(config);
}

// grab doc id from request
var id = request.query.docId;

// declare connection to firestore
var db = firebase.firestore();

// grab user from request
var docRef = db.collection("clients").doc(id);

// grab the users server and id
docRef.get().then(function(doc) {

// grab the account id
var accountId = doc.data().accountId;

// declare master variable that will be returned
var toReturn = [];

// declare variables that will be returned in toReturn
var gpmGames = [];
var cspmGames = [];
var damageGames = [];
var damageToChampionsGames = [];
var damageTakenGames = [];
var wardsGames = [];

db.collection('games')
  .where('accountId', '==', accountId)
  .get()
  .then((res) => {
    var games = res.docs;
    // iterate through games and get averages and totals to return
    games.forEach(function(game) {

      gpmGames.push(game.data().gpm);
      cspmGames.push(game.data().cspm);
      damageGames.push(game.data().damage);
      damageToChampionsGames.push(game.data().damagetochampions);
      damageTakenGames.push(game.data().damagerecieved);
      wardsGames.push(game.data().wards);

    });
  });

  toReturn['gpmGames'] = gpmGames;
  toReturn['cspmGames'] = cspmGames;
  toReturn['damageGames'] = damageGames;
  toReturn['damageToChampionsGames'] = damageToChampionsGames;
  toReturn['damageTakenGames'] = damageTakenGames;
  toReturn['wardsGames'] = wardsGames;

response.status(200).send(toReturn);
});

So I understand that my return is being called before everything is done running. How can I fix that? Of course, my return is giving an empty array and I get the error from firebase: Error: function crashed out of request scope Function invocation was interrupted.

Thanks!

3
  • I was thinking it might be a promise issue? Maybe create a helper function? Commented Feb 13, 2018 at 19:12
  • I don't see response.end() isn't it needed? Commented Feb 13, 2018 at 19:13
  • Ummmm.. I guess it might. I thought that could be used in place of response.send if nothing was to be sent back. Am I wrong in that regard and it is needed? Commented Feb 13, 2018 at 19:17

1 Answer 1

1

You have to use the promise that's returned from this:

db.collection('games')
  .where('accountId', '==', accountId)
  .get()

This is an asynchronous call, and it returns immediately with a promise that becomes resolved when the work is complete.

You need to use that promise to send the response at the right time:

const proimise = db.collection('games')
  .where('accountId', '==', accountId)
  .get()

promise.then(snapshot => {
    // work with the document snapshot here, and send your response
})
.catch(error => {
    // deal with any errors if necessary.
    response.status(500).send(error)
})

The way you're sending the response seems OK, you just need to wait till the fetch is done.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.