代码之家  ›  专栏  ›  技术社区  ›  Utku Ufuk

使用javascript承诺从firebase云函数读取google表单

  •  1
  • Utku Ufuk  · 技术社区  · 6 年前

    几个小时以来,我一直在努力解决一个涉及firebase云功能和google sheets api的问题。我只是想在一个 POST 请求我的云功能。

    下面的代码,我使用函数从电子表格中读取 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();
        });
    });
    

    然后我摆脱 小精灵 做任何事 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();
        });
    });
    

    但我得到了以下错误:

    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
        ...
    

    还有:

    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.
    

    我完全不理解这种行为。我只在不使用函数的情况下做同样的事情。我对javascript或node.js不是很有经验;如果有任何帮助,我将不胜感激。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Utku Ufuk    6 年前

    我设法通过更换线路来解决这个问题

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

    具有

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

    并将身份验证客户端直接传递给 sheets.spreadsheets.values.get 功能。

    所以就变成这样:

    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();
        });
    });