Search code examples
firebasegoogle-cloud-functionsaxioshttp-status-code-403google-books

403 status from Firebase Cloud Function -> Google Books API


I'm currently working on creating a Firebase Cloud Function that retrieve a list of books from the NYTimes API and grabs some additional information from the Google Books API. By using the following URL : "https://www.googleapis.com/books/v1/volumes?q=isbn:&key=" I'm able to retrieve books' details based on an ISBN.

My FREE quota for Google Books API is 1000 request per day and 100 request every 100 seconds per user. I'm only sending 15 requests and my current quota is below 200.

My key is restricted only to be used with Google Books API and it could be use from anywhere (iOS, web, android...etc)

After building the function I'm testing everything locally and data gets populated correctly although once I deploy the function on firebase I get a 403 status code when trying to access to the API.

Unfortunately I'm not getting more details about the error. It just this:

{ Error: Request failed with status code 403
    at createError (/user_code/node_modules/axios/lib/core/createError.js:16:15)
    at settle (/user_code/node_modules/axios/lib/core/settle.js:18:12)
    at IncomingMessage.handleStreamEnd (/user_code/node_modules/axios/lib/adapters/http.js:201:11)
    at emitNone (events.js:91:20)
    at IncomingMessage.emit (events.js:185:7)
    at endReadableNT (_stream_readable.js:974:12)
    at _combinedTickCallback (internal/process/next_tick.js:80:11)
    at process._tickDomainCallback (internal/process/next_tick.js:128:9)
  config: 
   { adapter: [Function: httpAdapter],
     transformRequest: { '0': [Function: transformRequest] },
     transformResponse: { '0': [Function: transformResponse] },
     timeout: 0,
     xsrfCookieName: 'XSRF-TOKEN',
     xsrfHeaderName: 'X-XSRF-TOKEN',
     maxContentLength: -1,
     validateStatus: [Function: validateStatus],
     headers: 
      { Accept: 'application/json, text/plain, */*',
        'User-Agent': 'axios/0.18.0' },
     method: 'get',
     url: 'https://www.googleapis.com/books/v1/volumes?q=isbn:0525520384&key=##########’,
     data: undefined },
  request: 
   ClientRequest {
     domain: null,
     _events: 
      { socket: [Function],
        abort: [Function],
        aborted: [Function],
        error: [Function],
        timeout: [Function],
        prefinish: [Function: requestOnPrefinish] },
     _eventsCount: 6,
     _maxListeners: undefined,
     output: [],
     outputEncodings: [],
     outputCallbacks: [],
     outputSize: 0,
     writable: true,
     _last: true,
     upgrading: false,
     chunkedEncoding: false,
     shouldKeepAlive: false,
     useChunkedEncodingByDefault: false,
     sendDate: false,
     _removedHeader: {},
     _contentLength: 0,
     _hasBody: true,
     _trailer: '',
     finished: true,
     _headerSent: true,
     socket: 
      TLSSocket {
        _tlsOptions: [Object],
        _secureEstablished: true,
        _securePending: false,
        _newSessionPending: false,
        _controlReleased: true,
        _SNICallback: null,
        servername: null,
        npnProtocol: false,
        alpnProtocol: false,
        authorized: true,
        authorizationError: null,
        encrypted: true,
        _events: [Object],
        _eventsCount: 10,
        connecting: false,
        _hadError: false,
        _handle: null,
        _parent: null,
        _host: 'www.googleapis.com',
        _readableState: [Object],
        readable: false,
        domain: null,
        _maxListeners: undefined,
        _writableState: [Object],
        writable: false,
        allowHalfOpen: false,
        destroyed: true,
        _bytesDispatched: 210,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: undefined,
        _server: null,
        ssl: null,
        _requestCert: true,
        _rejectUnauthorized: true,
        parser: null,
        _httpMessage: [Circular],
        read: [Function],
        _consuming: true,
        write: [Function: writeAfterFIN],
        _idleNext: null,
        _idlePrev: null,
        _idleTimeout: -1 },
     connection: 
      TLSSocket {
        _tlsOptions: [Object],
        _secureEstablished: true,
        _securePending: false,
        _newSessionPending: false,
        _controlReleased: true,
        _SNICallback: null,
        servername: null,
        npnProtocol: false,
        alpnProtocol: false,
        authorized: true,
        authorizationError: null,
        encrypted: true,
        _events: [Object],
        _eventsCount: 10,
        connecting: false,
        _hadError: false,
        _handle: null,
        _parent: null,
        _host: 'www.googleapis.com',
        _readableState: [Object],
        readable: false,
        domain: null,
        _maxListeners: undefined,
        _writableState: [Object],
        writable: false,
        allowHalfOpen: false,
        destroyed: true,
        _bytesDispatched: 210,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: undefined,
        _server: null,
        ssl: null,
        _requestCert: true,
        _rejectUnauthorized: true,
        parser: null,
        _httpMessage: [Circular],
        read: [Function],
        _consuming: true,
        write: [Function: writeAfterFIN],
        _idleNext: null,
        _idlePrev: null,
        _idleTimeout: -1 },
     _header: 'GET /books/v1/volumes?q=isbn:0525520384&key=##### HTTP/1.1\r\nAccept: application/json, text/plain, */*\r\nUser-Agent: axios/0.18.0\r\nHost: www.googleapis.com\r\nConnection: close\r\n\r\n',
     _headers: 
      { accept: 'application/json, text/plain, */*',
        'user-agent': 'axios/0.18.0',
        host: 'www.googleapis.com' },
     _headerNames: { accept: 'Accept', 'user-agent': 'User-Agent', host: 'Host' },
     _onPendingData: null,
     agent: 
      Agent {
        domai

Solution

  • I was facing a similar issue. I was able to sucessfully use the Books API when I was running my functions locally (ie. firebase serve). But when I deployed the functions and the app to hosting, I was getting a mysterious 403: Forbidden error.

    I tried several things so I'm not sure which helped so I'll just list everything:

    • Updated firebase functions: npm install --save firebase-functions@latest
    • Switched from using node-fetch to using axios for calling the API
    • Add country to URL: https://www.googleapis.com/books/v1/volumes?country=US&q=insubject:${randomWord}&key=${functions.config().books.api.key}
    • Regenerated Google Books API key
    • Removed all Application restrictions in the google cloud console

    Hope this helps somebody out there because I was wrestling with it for hours!