Search code examples
javascriptfirebasegoogle-cloud-functions

Firebase Cloud Functions: Difference between onRequest and onCall


Going through the docs, I encountered:

...you can call functions directly with an HTTP request or a call from the client.

~ source

there (link in the quote) is a mention about functions.https.onCall.

But in the tutorial here, another function functions.https.onRequest is used, so which one should I use and why? What is the difference/similarity between them?

Documentation for functions.https is here.


Solution

  • The official documentation for those is really helpful, but from the view of an amateur, the described differences were confusing at first.

    • Both types, when deployed, are assigned with a unique HTTPS endpoint URL and can be accessed directly using an https client.

    • However, there is one important difference in the way how they are supposed to be called.

      • onCall: from the client's firebase.functions()
      • onRequest: via standard https client (e.g. fetch() API in JS)

    onCall

    • Can be invoked (and this is also the main purpose) directly from the client app.

       functions.httpsCallable('getUser')({uid})
         .then(r => console.log(r.data.email))
      
    • It is implemented with user-provided data and automagic context.

       export const getUser = functions.https.onCall((data, context) => {
         if (!context.auth) return {status: 'error', code: 401, message: 'Not signed in'}
         return new Promise((resolve, reject) => {
           // find a user by data.uid and return the result
           resolve(user)
         })
       })
      
    • The context automagically contains metadata about the request such as uid and token.

    • Input data and response objects are automatically (de)serialized.

    onRequest

    • Firebase onRequest Docs

    • Serves mostly as an Express API endpoint.

    • It is implemented with express Request and Response objects.

       export const getUser = functions.https.onRequest((req, res) => {
         // verify user from req.headers.authorization etc.
         res.status(401).send('Authentication required.')
         // if authorized
         res.setHeader('Content-Type', 'application/json')
         res.send(JSON.stringify(user))
       })
      
    • Depends on user-provided authorization headers.

    • You are responsible for input and response data.

    Read more here Is the new Firebase Cloud Functions https.onCall trigger better?