Is there a way to authenticate the user using its email address and password? In the Firebase Admin SDK package, Go language, I found no “Sign in” function. To create a CustomToken you don’t need the user’s password. I could create a Sign up/Register function using the CreateUser function.
CustomToken
CreateUser
The frontend is written in Flutter and yes, I know, it would be possible to implement the authentication directly in the frontend, but I would like to avoid it.
func (svc *AuthenticationService) Login(ctx context.Context, req *LoginRequest) (*AuthResponse, error) { initFirebase() authToken, err := authClient.CustomToken(context.Background(), req.EmailAddress) if err != nil { return &AuthResponse{ Result: Result_LOGIN_FAILED, Token: "", }, errors.New("login failed: " + err.Error()) } return &AuthResponse{ Result: Result_LOGIN_SUCCEDED, Token: authToken, }, nil }
Firebase Authentication typically involves using the Firebase Authentication client libraries in your frontend (Flutter in this case) to authenticate users. The client libraries provide methods for signing up, signing in, and managing user accounts securely.
In your Go backend (Firebase Admin SDK), you usually won’t directly handle user authentication, especially user login with email and password. Instead, the login process should be handled on the client side, and once the user is authenticated, you can pass the token (for example, a Firebase ID token) to your Go backend for further verification and to perform authorized operations.
Here’s a high-level approach:
signInWithEmailAndPassword
Here’s a simplified example of how the flow might look:
Frontend (Flutter):
// Example using FirebaseAuth library in Flutter import 'package:firebase_auth/firebase_auth.dart'; Future<void> signInWithEmailAndPassword(String email, String password) async { try { UserCredential userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword( email: email, password: password, ); print('User signed in: ${userCredential.user!.uid}'); // Send the ID token to the backend sendTokenToBackend(await userCredential.user!.getIdToken()); } catch (e) { print('Failed to sign in: $e'); } } void sendTokenToBackend(String token) { // Send the token to your Go backend // You might use HTTP, gRPC, or other communication methods }
Backend (Go):
// Example in your Go backend using Firebase Admin SDK func handleUserToken(token string) (*User, error) { // Verify the token using Firebase Admin SDK decodedToken, err := authClient.VerifyIDToken(context.Background(), token) if err != nil { return nil, err } // Access user information from the decoded token uid := decodedToken.UID email := decodedToken.Claims["email"].(string) // Perform further backend operations with the user information // ... return &User{ UID: uid, Email: email, }, nil }
In this example, the Flutter app handles user authentication using the Firebase Authentication library. After successful login, it obtains the ID token and sends it to the Go backend. The Go backend then verifies the token using the Firebase Admin SDK and extracts user information from the decoded token.
Remember to secure your communication between the frontend and backend to prevent unauthorized access or interception of sensitive information.