简体   繁体   English

使用JavaScript Promise从Firebase云功能读取Google表格

[英]Reading Google Sheets from Firebase cloud functions using javascript promises

For hours I've been struggling with a problem involving Firebase Cloud Functions & Google Sheets API. 几个小时以来,我一直在解决涉及Firebase Cloud Functions和Google Sheets API的问题。 I'm simply trying to read some cells in my spreadsheet upon a POST request to my Cloud Function. 我只是在尝试向Cloud Function发送POST请求时读取电子表格中的某些单元格。

The following code, where I read from the spreadsheet using a function readCells works just fine: 我使用readCells函数从电子表格读取以下代码的效果很好:

const {google} = require('googleapis');
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
var db = admin.firestore();

// magic function (?)
function readCells(auth, ssheetId) {
    const sheets = google.sheets({version: 'v4', auth});
    return new Promise((resolve, reject) => {
        sheets.spreadsheets.values.get({spreadsheetId:ssheetId,
                                        range:'MySheet!A1:A2'},
                                        (err, result) => {
            if (err) {
                reject(err);
            }
            resolve(result);
        });
    });
}

exports.test = functions.https.onRequest((request, response) => {
    // read auth token & spreadsheet ID from Cloud Firestore        
    let tokenPromise = db.doc('config/token').get();
    let spreadsheetPromise = db.doc('config/spreadsheet').get();

    // read from spreadsheet
    return Promise.all([tokenPromise, spreadsheetPromise]).then(results => {
        const token = results[0].data();
        const ssheetId = results[1].data().id;
        const oAuth2Client = new google.auth.OAuth2(token.client_id, token.client_secret, "");
        oAuth2Client.setCredentials(token);
        return readCells(oAuth2Client, ssheetId);
    })
    .then(result => {
        console.log(result.data.values);
        return response.status(200).end();
    })
    .catch(err => {
        console.error(err);
        return response.status(500).end();
    });
});

Then I get rid of readCells and do everything in the HTTPS cloud function test : 然后,我摆脱了readCells并进行了HTTPS云功能test

exports.test = functions.https.onRequest((request, response) => {
    // read auth token & spreadsheet ID from Cloud Firestore
    let tokenPromise = db.doc('config/token').get();
    let spreadsheetPromise = db.doc('config/spreadsheet').get();

    // read from spreadsheet
    return Promise.all([tokenPromise, spreadsheetPromise]).then(results => {
        const token = results[0].data();
        const ssheetId = results[1].data().id;
        const oAuth2Client = new google.auth.OAuth2(token.client_id, token.client_secret, "");
        oAuth2Client.setCredentials(token);
        const sheets = google.sheets({version: 'v4', oAuth2Client});
        return new Promise((resolve, reject) => {
            sheets.spreadsheets.values.get({spreadsheetId:ssheetId,
                                            range:'MySheet!A1:A2'},
                                            (err, result) => {
                if (err) {
                    reject(err);
                }
                resolve(result);
            });
        });
    })
    .then(result => {
        console.log(result.data.values);
        return response.status(200).end();
    })
    .catch(err => {
        console.error(err);
        return response.status(500).end();
    });
});

But I get the following error: 但是我收到以下错误:

error: { Error: The request is missing a valid API key.
    at createError (/<path_to_functions>/node_modules/axios/lib/core/createError.js:16:15)
    at settle (/<path_to_functions>/node_modules/axios/lib/core/settle.js:18:12)
    at IncomingMessage.handleStreamEnd (/<path_to_functions>/node_modules/axios/lib/adapters/http.js:201:11)
    at emitNone (events.js:111:20)
    at IncomingMessage.emit (events.js:208:7)
    at endReadableNT (_stream_readable.js:1064:12)
    at _combinedTickCallback (internal/process/next_tick.js:138:11)
    at process._tickCallback (internal/process/next_tick.js:180:9)
    ...
    more stuff
    ...

And also: 并且:

error: (node:3308) UnhandledPromiseRejectionWarning: 
Unhandled promise rejection. This error originated either by throwing
inside of an async function without a catch block,
or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:3308) [DEP0018] DeprecationWarning: Unhandled promise rejections
are deprecated. In the future, promise rejections that are not handled
will terminate the Node.js process with a non-zero exit code.

I don't understand this behaviour at all. 我完全不了解这种行为。 I do the same thing only without using a function. 我只是在不使用函数的情况下做同样的事情。 I'm not very experienced in Javascript or Node.js; 我对Javascript或Node.js不太了解; any help would be appreciated. 任何帮助,将不胜感激。

I managed to solve the problem by replacing the line 我设法通过替换生产线解决了问题

const sheets = google.sheets({version: 'v4', oAuth2Client});

with

const sheets = google.sheets('v4');

and passing the auth client directly to sheets.spreadsheets.values.get function. 并将身份验证客户端直接传递给sheets.spreadsheets.values.get函数。

So it became like this: 这样就变成了这样:

exports.test = functions.https.onRequest((request, response) => {
    let tokenPromise = db.doc('config/token').get();
    let spreadsheetPromise = db.doc('config/spreadsheet').get();
    return Promise.all([tokenPromise, spreadsheetPromise]).then(results => {
        const token = results[0].data();
        const ssheetId = results[1].data().id;
        const oAuth2Client = new google.auth.OAuth2(token.client_id, token.client_secret);
        oAuth2Client.setCredentials(token);
        const sheets = google.sheets('v4');
        return new Promise((resolve, reject) => {
            sheets.spreadsheets.values.get({spreadsheetId: ssheetId,
                                            auth: oAuth2Client,
                                            range: "MySheet!A1:A2"}, (err, result) => {
                if (err) {
                    reject(err);
                }
                resolve(result);
            });
        })
    })
    .then(result => {
        console.log(result.data.values[0][0]);
        return response.status(200).end();
    })
    .catch(err => {
        console.error(err);
        return response.status(500).end();
    });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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