简体   繁体   中英

Error: could not load the default credentials — creds are fine, function dies

All of my other functions are working fine and this function works with a limited data set, so it's not really a credentials problem. It appears that I am running into the issue describes in these answers:

https://stackoverflow.com/a/58828202/3662110

https://stackoverflow.com/a/58779000/3662110

I'm fetching a pretty large chunk of JSON, so I think the issue is similar in that it's timing out, but I'm unable to add return or await in the same way described in those answers (tried them both, but return does nothing and await causes another error) because I'm looping through the data and writing many documents. This function has worked in the past when I limit the number of results fetched from the API. How do I keep the function alive long enough to write all the data?

const functions = require('firebase-functions');
const admin = require('firebase-admin');

exports.fetchPlayers = functions.pubsub
    .schedule('every Tuesday of sep,oct,nov,dec 6:00')
    .timeZone('America/New_York')
  .onRun(async context => {
        const response =  fetch(
            `<<< the endpoint >>>`,
            {<<< the headers >>>}
        )
        .then(res => {
            <<< handle stuff >>>
        })
        .then(res => res.json());

        const resObj = await response;
        const players = [];

        resObj.dfsEntries[0].dfsRows.forEach(x => {
            <<< extract the data >>>
            players.push({ id, fName, lName, pos, team, [week]: fp });
        })

        players.forEach(player =>
            admin
                .firestore()
                .collection('players')
                .doc(`${player.id}`)
                .set(player, {merge: true})
                .then(writeResult => {
                    // write is complete here
                })
        );
});

In order to correctly terminate a Cloud Function , you are required to return a promise from the function that resolves when all of the asynchronous work is complete. You can't ignore any promises. Calling then on a promise isn't enough, since then just returns another promise. The problem is that you're ignoring the promises generated inside the forEach loop. You will need to collect all those promises in an array, then use Promise.all() to create a new promise that you can return from the function. To put it briefly:

const promises = players.map(player => {
    return admin.firestore....set(...)
})
return Promise.all(promises)

If you don't wait for all the promises to resolve, then the function will terminate and shut down early, before the async work is done.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM