Search code examples
typescriptfirebasegoogle-cloud-functionsgoogle-books

HttpsError when calling Google Books API from Firebase Cloud Function


I'm trying to create a Firebase Cloud Function that performs a search on the Google Books API.

export const searchBooksOnline = functions.https.onCall(
    async function(data: any, context: functions.https.CallableContext) {
        const query: string = data.query;
        console.log(`Received query loud and clear: ${query}`);
        try {
            const res = await fetch(`https://www.googleapis.com/books/v1/volumes?q=${query}&key=MY-API-KEY`);
            const json = await res.json();
            return json;
        } catch(err) {
            throw new functions.https.HttpsError(err.status, 'Failed to search books online');
        }
    }
);

But whenever I call this function from the Javascript API, I get an error:

Unhandled error Error: Unknown error code: undefined.
    at new HttpsError (/srv/node_modules/firebase-functions/lib/providers/https.js:95:19)
    at exports.searchBooksOnline (/srv/lib/books.js:42:15)
    at func (/srv/node_modules/firebase-functions/lib/providers/https.js:267:32)
    at <anonymous>
    at process._tickDomainCallback (internal/process/next_tick.js:229:7)

which is quite cryptic to me. I know that the function is getting called properly because

  • I can see my print in the Cloud Functions log "Received query loud and clear:".

  • When I remove the await fetch line and return some dummy data, the function executes correctly.

Additionally, I'm sure that the API call is working because when I copy out those few lines to run directly from my browser's developer console, I get the expected API response.

I'm not sure what is different about the Cloud Functions environment that is causing this error. (I'm on the Blaze plan, which should allow me to make requests to external sites)

Hope that somebody can help shed some light on this!

(I have seen this similar issue, but the solution applied by the OP does not make a difference to me, I still have the same error.)


Solution

  • The answer from Doug Stevenson didn't solve the problem directly, but helped me to diagnose it:

    As soon as I fixed my HttpsError report as he suggested, I tried calling the function again and this time it gave me an error message saying 'fetch' not defined. Turns out that fetch which I was testing successfully from client-side JavaScript is not natively implemented in NodeJS (which Cloud Functions use).

    So the fix was simply to use a different method for my API request. In my case, I chose to use node-fetch, which implements the same interface as the JavaScript fetch function.

    So the only change I need to get things working was to do

    npm install node-fetch @types/node-fetch # the @types package needed for TypeScript
    

    and then

    import fetch from 'node-fetch';
    

    at the top of my code.