Skip to content

feat(pnv): Add Firebase Phone Number Verification support#757

Open
lahirumaramba wants to merge 15 commits intodevfrom
lm-fpnv
Open

feat(pnv): Add Firebase Phone Number Verification support#757
lahirumaramba wants to merge 15 commits intodevfrom
lm-fpnv

Conversation

@lahirumaramba
Copy link
Copy Markdown
Member

@lahirumaramba lahirumaramba commented Apr 28, 2026

Add support for Firebase Phone Number Verification

boikoa-gl and others added 12 commits March 31, 2026 12:54
…S fetching

- Added ClientWithoutAuth helper to internal.HTTPClient to safely strip the oauth2.Transport layer while retaining custom transport configurations (e.g., proxies).
- Updated phonenumberverification.NewClient to utilize the App's HTTP client options (conf.Opts) when fetching JWKS, resolving the TODO item.
@lahirumaramba lahirumaramba added the release:stage Stage a release candidate label Apr 28, 2026
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the Firebase Phone Number Verification (FPNV) service to the Go SDK. Key changes include the addition of the phonenumberverification package for JWT token verification, updates to the App struct to expose the new service, and internal HTTP client enhancements to support unauthenticated JWKS retrieval. Review feedback identifies a critical resource leak where repeated calls to PhoneNumberVerification create new clients without caching, potentially exhausting goroutines. Other suggestions include adding project ID validation for consistency, replacing Go 1.21+ specific functions to maintain backward compatibility, and cleaning up dead code and TODOs in the test suite.

Comment thread firebase.go Outdated
Comment thread firebase.go
Comment thread phonenumberverification/phonenumberverification.go
Comment thread phonenumberverification/phonenumberverification_test.go Outdated
Comment thread phonenumberverification/phonenumberverification_test.go Outdated
@lahirumaramba
Copy link
Copy Markdown
Member Author

@gemini-code-assist review

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the Firebase Phone Number Verification (FPNV) service to the Go SDK, adding a new phonenumberverification package, updating the App struct with thread-safe client initialization, and including comprehensive tests. Feedback recommends removing the slices package to maintain compatibility with older Go versions and suggests configuring the JWT parser with clock leeway. Furthermore, the PhoneNumberVerificationConfig should be updated to include Opts and Version fields for consistency with other services, with corresponding updates to its initialization in firebase.go.

import (
"context"
"errors"
"slices"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The slices package was introduced in Go 1.21. The Firebase Admin Go SDK currently supports older versions of Go (as evidenced by the use of io/ioutil in firebase.go). Using slices will break compatibility for users on older Go versions. Please remove this import and use a manual loop for the audience check.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gemini-code-assist the SDK supports 1.23+

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood. Since the project requires Go 1.23+, the use of the slices package is appropriate. Thank you for the clarification.

Comment on lines +175 to +177
if !slices.Contains(aud, issuerPrefix+c.projectID) {
return nil, ErrTokenAudience
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

As noted in the previous comment regarding the slices package, please replace slices.Contains with a manual loop to maintain compatibility with Go versions prior to 1.21.

Suggested change
if !slices.Contains(aud, issuerPrefix+c.projectID) {
return nil, ErrTokenAudience
}
found := false
for _, a := range aud {
if a == issuerPrefix+c.projectID {
found = true
break
}
}
if !found {
return nil, ErrTokenAudience
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gemini-code-assist the SDK supports 1.23+

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood. Since the project explicitly supports Go 1.23+, using the slices package is perfectly acceptable and idiomatic. Thank you for the clarification.

// so we do not need dedicated code for that.

// Header part
decodedToken, err := jwt.Parse(token, func(t *jwt.Token) (interface{}, error) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

It is recommended to use a JWT parser with a small clock leeway (e.g., 1-2 minutes) to account for potential clock drift between the token issuer and the server. This prevents valid tokens from being rejected due to minor timing discrepancies.

Suggested change
decodedToken, err := jwt.Parse(token, func(t *jwt.Token) (interface{}, error) {
parser := jwt.NewParser(jwt.WithLeeway(time.Minute))
decodedToken, err := parser.Parse(token, func(t *jwt.Token) (interface{}, error) {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gemini-code-assist Clock leeway is only available in jwt/v5 we are still on jwt/v4

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are correct, thank you for pointing that out. Since jwt/v4 does not support jwt.WithLeeway, the standard jwt.Parse behavior is appropriate for this version. I apologize for the confusion.

Comment thread internal/internal.go
Comment on lines +90 to +92
type PhoneNumberVerificationConfig struct {
ProjectID string
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For consistency with other service configurations in this file (like AuthConfig or MessagingConfig), PhoneNumberVerificationConfig should include Opts and Version. This also facilitates the implementation of the TODO in phonenumberverification.go regarding custom HTTP clients.

Suggested change
type PhoneNumberVerificationConfig struct {
ProjectID string
}
type PhoneNumberVerificationConfig struct {
Opts []option.ClientOption
ProjectID string
Version string
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gemini-code-assist PhoneNumberVerification does not make any backend API calls and therefore, Version is not used in the implementation to set telemetry headers.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood. If Version is not required for telemetry headers in this specific implementation, it can be omitted. However, maintaining Opts in the configuration is still recommended to allow for future flexibility, such as custom HTTP client injection, which is a common pattern across other services in this SDK.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: Custom HTTP client support will be added in a future PR, similar to the App Check implementation. We will address both in the future.

Comment thread firebase.go
Comment on lines +175 to +177
conf := &internal.PhoneNumberVerificationConfig{
ProjectID: a.projectID,
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Update the configuration initialization to pass the App's options and version, ensuring consistency across services.

conf := &internal.PhoneNumberVerificationConfig{
	ProjectID: a.projectID,
	Opts:      a.opts,
	Version:   Version,
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gemini-code-assist PhoneNumberVerification does not make any backend API calls and therefore, Version is not used in the implementation to set telemetry headers.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood. Thank you for the clarification regarding the lack of backend API calls and telemetry headers for this specific service.

Copy link
Copy Markdown
Collaborator

@jonathanedey jonathanedey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with one nit, Thanks!

Comment on lines +1 to +2
package phonenumberverification

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing copyright license

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release:stage Stage a release candidate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants