Matti
Matti

Reputation: 484

Using Firebase Admin SDK for Go from AppEngine

while writing a AppEngine/Go backend that would want to verify firebase id tokens (jwt) I ran across this problem running it on AppEngine:

http.DefaultTransport and http.DefaultClient are not available in App Engine. See https://cloud.google.com/appengine/docs/go/urlfetch/

The Admin SDK is described here: https://firebase.google.com/docs/admin/setup

The following might fix it, only if client.ks was an exported property and thus writable from the app using the lib:

client, err := app.Auth()
if err != nil {
    log.Errorf(ctx, "Error getting auth client: %v", err)
    writeJsonResponse(ctx, w, apiResponse{Message: "Firebase error"},
        http.StatusInternalServerError)
    return
}

// Override the HTTP client by using the urlfetch client to
// make it work under AppEngine
client.ks.HTTPClient = urlfetch.Client(ctx)

Are my options limited to a) forking this and manually adding support for urlfetch b) looking for another solutions besides the seemingly OFFICIAL one.. :o

EDIT: As suggested by Gavin, I tried changing this to the following:

// Override the default HTTP client with AppEngine's urlfetch
opt := option.WithHTTPClient(urlfetch.Client(ctx))

app, err := firebase.NewApp(ctx, nil, opt)
if err != nil {
    log.Errorf(ctx, "Error initializing firebase app: %v", err)
    writeJsonResponse(ctx, w, apiResponse{Message: "Firebase error"},
        http.StatusInternalServerError)
    return
}

This, however, doesn't do the trick. As far as I can see (having done some source diving in the said library "firebase.google.com/go"), the http.Client passed in through the options.Client is only used for Creds creation:

creds, err := transport.Creds(ctx, o...)

And the actual HTTP communication done in method refreshKeys() of crypto.go does not use this; instead, it attempts to use the HTTPClient property set in the httpKeySource. IMO this is never set anywhere, and therefore it always defaults to the http.DefaultClient.

Upvotes: 0

Views: 755

Answers (1)

Gavin
Gavin

Reputation: 4515

When creating a new application with the Firebase Admin SDK, you can pass in options from the "google.golang.org/api/option" package. The option you want to pass in is WithHTTPClient.

func handleRequest(w http.ResponseWriter, r *http.Request) {
    ctx := appengine.NewContext(r)
    opt := option.WithHTTPClient(urlfetch.Client(ctx))
    app, err := firebase.NewApp(ctx, config, opt)
    ...
}

Upvotes: 1

Related Questions