95
votes

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.

1
Thank you @DougStevenson, but I have read that question prior to asking this one and it did not help me understand the topic better.Qwerty
I don't think there's anything else to understand. What is your specific confusion?Doug Stevenson
@DougStevenson For one, there seems to be a difference in how those functions can be invoked. One via url, other using an in-app call.Qwerty
@DougStevenson Can you check my answer for possible mistakes please? Thanks!Qwerty

1 Answers

122
votes

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.

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?