# Firebase Authentication
###### tags: `olympus`
## User Management
[Firebase official docs](https://firebase.google.com/docs/auth/admin/manage-users#go)
### Official user struct fields
- Disabled `bool`
- DisplayName `string`
- Email `string`
- EmailVerified `bool`
- Password `string`
- PhoneNumber `string`
- PhotoURL `string`
- UID `string`
### Custom token
- Create a new mock user
```go=
user := (&auth.UserToCreate{}).
Email("user@example.com").
EmailVerified(false).
PhoneNumber("+15555550100").
Password("secretPassword").
DisplayName("John Doe").
PhotoURL("http://www.example.com/12345678/photo.png").
Disabled(false)
record, err := a.CreateUser(ctx, user)
```
- Check this user
```go=
users, errs := a.ListUsers(ctx)
if len(errs) != 0 {
log.Fatalf("Failed to list users: %#v", errs)
}
log.Infof("user: %#v", users[0])
```

---
- Token minting with claims
```go=
claim := map[string]interface{}{
"policies": []string{
"user.create",
"user.update",
},
}
tokenId := a.CreateCustomTokenWithClaims(ctx, users[0].UID, claim)
log.Infof("tokenId: %#v", tokenId)
```

---
- Website sign-in emulation
<details>
<summary>emulator</summary>
```go=
package clients
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
const (
verifyCustomTokenURL = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyCustomToken?key=%s"
)
func SignInWithCustomToken(token string) (string, error) {
req, err := json.Marshal(map[string]interface{}{
"token": token,
"returnSecureToken": true,
})
if err != nil {
return "", err
}
// How to get the key?
// https://developers.google.com/maps/documentation/places/web-service/get-api-key#gcloud-restrict
apiKey := "AIzaSyAbCnHvR0cbTbH-E9cOpYGc9-q8aTAWD5M"
resp, err := postRequest(fmt.Sprintf(verifyCustomTokenURL, apiKey), req)
if err != nil {
return "", err
}
var respBody struct {
IDToken string `json:"idToken"`
}
if err := json.Unmarshal(resp, &respBody); err != nil {
return "", err
}
return respBody.IDToken, err
}
func postRequest(url string, req []byte) ([]byte, error) {
resp, err := http.Post(url, "application/json", bytes.NewBuffer(req))
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected http status code: %d", resp.StatusCode)
}
return ioutil.ReadAll(resp.Body)
}
```
</details>
```go=
token, err := clients.SignInWithCustomToken(tokenId)
if err != nil {
log.Fatalf("Failed to sign in: %v", err)
}
log.Infof("token: %#v", token)
```

---
- Server side verify id token
```go=
aToken := a.VerifyIdToken(ctx, token)
log.Infof("aToken: %#v", aToken)
```

---
## Custom user claims
```go=
```