Use Firebase Auth with your app
Encore's authentication support provides a simple yet powerful way of dealing with various authentication scenarios.
Firebase Authentication is a common solution for quickly setting up a user store and simplifying social logins.Encore makes it really easy to integrate with Firebase Authentication on the backend.
For all the code and instructions of how to clone and run this example locally, see the Firebase Auth Example in our examples repo.
Set up auth handler
First, install two modules:
$ go get firebase.google.com/go/v4 go4.org/syncutil
Next it's time to define your authentication handler.
It can live in whatever service you'd like, but it's usually easiest
to create a designated user
service.
Create the user/user.go
file and add the following skeleton code:
package user
import (
"context"
"strings"
"encore.dev/beta/auth"
firebase "firebase.google.com/go/v4"
fbauth "firebase.google.com/go/v4/auth"
"go4.org/syncutil"
"google.golang.org/api/option"
)
// Data represents the user's data stored in Firebase Auth.
type Data struct {
// Email is the user's email.
Email string
// Name is the user's name.
Name string
// Picture is the user's picture URL.
Picture string
}
// ValidateToken validates an auth token against Firebase Auth.
//encore:authhandler
func ValidateToken(ctx context.Context, token string) (auth.UID, *Data, error) {
panic("Not Yet Implemented")
}
Initialize Firebase SDK
Next, let's set up the Firebase Auth client. We'll use
syncutil.Once
to do it lazily the first time we need it.
Add to the bottom of our file:
var (
fbAuth *fbauth.Client
setupOnce syncutil.Once
)
// setupFB ensures Firebase Auth is setup.
func setupFB() error {
return setupOnce.Do(func() error {
opt := option.WithCredentialsJSON([]byte(secrets.FirebasePrivateKey))
app, err := firebase.NewApp(context.Background(), nil, opt)
if err == nil {
fbAuth, err = app.Auth(context.Background())
}
return err
})
}
var secrets struct {
// FirebasePrivateKey is the JSON credentials for calling Firebase.
FirebasePrivateKey string
}
Validate token against Firebase
Now that we have the code to initialize Firebase Auth, we can use it from our ValidateToken
auth handler.
Update the function to look like the following:
func ValidateToken(ctx context.Context, token string) (auth.UID, *Data, error) {
if err := setupFB(); err != nil {
return "", nil, err
}
tok, err := fbAuth.VerifyIDToken(ctx, token)
if err != nil {
return "", nil, err
}
email, _ := tok.Claims["email"].(string)
name, _ := tok.Claims["name"].(string)
picture, _ := tok.Claims["picture"].(string)
uid := auth.UID(tok.UID)
usr := &Data{
Email: email,
Name: name,
Picture: picture,
}
return uid, usr, nil
}
Great! We're done with the code. Now we just need to set up the secret.
Set Firebase secret credentials
If you haven't already, set up a Firebase project.
Then, go to Project settings and navigate to Service accounts.
Select Go
as the language of choice and click Generate new private key
.
Download the generated key and take note where it is stored.
Next, store the private key as your firebase secret. From your terminal (inside your Encore app directory), run:
$ encore secret set --type prod FirebasePrivateKey < /path/to/firebase-private-key.jsonSuccessfully updated production secret FirebasePrivateKey
Now you should do the same for the development secret. The most secure way is to set up a different Firebase project and use that for development.
Depending on your security requirements you could also use the same Firebase project, but we recommend generating a new private key for development in that case.
Once you have a private key for development, set it similarly to before:
$ encore secret set --type dev,local,pr FirebasePrivateKey < /path/to/firebase-private-key.jsonSuccessfully updated development secret FirebasePrivateKey
That's it! You can now call your Encore application and pass in Firebase tokens. Encore will run your auth handler and validate the token against Firebase Auth.
Frontend
Firebase offers a npm package for your web frontend which makes it really simple to create a login/signup flow inside your web app as well as getting the token required to communicate with your Encore backend.
For a fully working backend + frontend example see the Firebase Auth Example in our examples repo.