Проблема с access_token: работа с облачной функцией для автоматического обновления листа Google при добавлении данных в базу данных firestore - PullRequest
0 голосов
/ 18 октября 2019

Я пытаюсь отправить данные из базы данных пожарного магазина на лист Google, чтобы каждый раз, когда я что-то добавлял в свою базу данных пожарного магазина, он добавлял новую строку в лист Google. Вот мой код:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const {OAuth2Client} = require('google-auth-library');
const {google} = require('googleapis');


const { Storage } = require('@google-cloud/storage');
const os = require('os');
const path = require('path');
const spawn = require('child-process-promise').spawn;

const db = admin.database();


// // Create and Deploy Your First Cloud Functions
// // https://firebase.google.com/docs/functions/write-firebase-functions
//
// exports.helloWorld = functions.https.onRequest((request, response) => {
//  response.send("Hello from Firebase!");
// });

const CONFIG_CLIENT_ID = functions.config().googleapi.client_id;
const CONFIG_CLIENT_SECRET = functions.config().googleapi.client_secret;
const CONFIG_SHEET_ID = functions.config().googleapi.sheet_id;

const CONFIG_DATA_PATH = functions.config().watchedpaths.data_path;

// The OAuth Callback Redirect.
const FUNCTIONS_REDIRECT = 'https://us-central1-c39-mwk-dev.cloudfunctions.net/oauthcallback';

// setup for authGoogleAPI
const SCOPES = ['https://www.googleapis.com/auth/spreadsheets'];
const functionsOauthClient = new OAuth2Client(CONFIG_CLIENT_ID, CONFIG_CLIENT_SECRET,
  FUNCTIONS_REDIRECT);

//const FUNCTIONS_REDIRECT = 'https://c39-mwk-dev.firebaseio.com.cloudfunctions.net/OauthCallback';
// TODO: use firebase functions:config:set to configure your Google API client ID and secret
// Also update FUNCTIONS_REDIRECT

//const auth = new googleAuth();
let oauthTokens = null;

// visit the URL for this Function to request tokens
exports.authgoogleapi = functions.https.onRequest((req, res) => {
  res.set('Cache-Control', 'private, max-age=0, s-maxage=0');
  res.redirect(functionsOauthClient.generateAuthUrl({
    access_type: 'offline',
    scope: SCOPES,
    prompt: 'consent',
  }));
});

  // after you grant access, you will be redirected to the URL for this Function
  // this Function stores the tokens to your Firebase database
  // const DB_TOKEN_PATH = '/api_tokens';
  // exports.OauthCallback = functions.https.onRequest((req, res) => {
  //   const code = req.query.code;
  //   functionsOauthClient.getToken(code, (err, tokens) => {
  //     // Now tokens contains an access_token and an optional refresh_token. Save them.
  //     if (err) {
  //       return res.status(400).send(err);
  //     }
  //     return db.ref(DB_TOKEN_PATH).set(tokens).then(() => res.status(200).send('OK'));
  //   });
  // });

  const DB_TOKEN_PATH = '/api_tokens';
  exports.oauthcallback = functions.https.onRequest(async (req, res) => {
    res.set('Cache-Control', 'private, max-age=0, s-maxage=0');
    const code = req.query.code;
    try {
      const {tokens} = await functionsOauthClient.getToken(code);
      // Now tokens contains an access_token and an optional refresh_token. Save them.
      await admin.database().ref(DB_TOKEN_PATH).set(tokens);
      return res.status(200).send('App successfully configured with new Credentials. '
          + 'You can now close this page.');
    } catch (error) {
      return res.status(400).send(error);
    }
  });

  const SHEET_ID = 'my-sheet-id';

  exports.appendRecordToSpreadsheet = functions.firestore.document('incident-report/{id}').onCreate(
    async(snap, context) => {
        console.log('I am triggered');
      const newRecord = snap.data();
      console.log(newRecord);
      return appendPromise({
        spreadsheetId: SHEET_ID,
        range: 'A:C',
        valueInputOption: 'USER_ENTERED',
        insertDataOption: 'INSERT_ROWS',
        resource: {
          values: [["aaa", "bb", "aa"]]
        }
      });
  });


  function appendPromise(requestWithoutAuth) {
    return new Promise((resolve, reject) => {
      return getAuthorizedClient().then((client) => {
        const sheets = google.sheets('v4');
        const request = requestWithoutAuth;
        request.auth = client;
        return sheets.spreadsheets.values.append(request, (err, response) => {
          if (err) {
            console.log(`The API returned an error: ${err}`);
            return reject(err);
          }
          return resolve(response.data);
        });
      });
    });
  }


// checks if oauthTokens have been loaded into memory, and if not, retrieves them
async function getAuthorizedClient() {
  if (oauthTokens) {
    return functionsOauthClient;
  }
  const snapshot = await admin.database().ref(DB_TOKEN_PATH).once('value');
  oauthTokens = snapshot.val();
  functionsOauthClient.setCredentials(oauthTokens);
  return functionsOauthClient;
}

Я получаю эту ошибку в журнале функций firebase:

TypeError: Невозможно прочитать свойство 'access_token' из null в OAuth2Client.getRequestMetadataAsync (/ srv / node_modules /google-auth-library / build / src / auth / oauth2client.js: 247: 24) в OAuth2Client.requestAsync (/srv/node_modules/google-auth-library/build/src/auth/oauth2client.js:336:34)в OAuth2Client.request (/srv/node_modules/google-auth-library/build/src/auth/oauth2client.js:330:25) в createAPIRequestAsync (/srv/node_modules/googleapis-common/build/srsjs:248: 27) в Object.createAPIRequest (/srv/node_modules/googleapis-common/build/src/apirequest.js:44:9) в ресурсе $ Spreadsheets $ Values.append (/ srv / node_modules / googleapis / build / src /apis / sheet / v4.js: 320: 37) в getAuthorizedClient.then (/srv/index.js:111:43) в process._tickDomainCallback (внутренняя / process / next_tick.js: 229: 7)

Кто-нибудь может мне помочь с этим?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...