React+Firebase项目:如何将邮箱登录改为用户名密码登录?
Got it, let's tackle this! Firebase Auth doesn't natively support username/password login out of the box, but we can work around this by first looking up the user's email via their username (stored in Firestore or Realtime Database) and then using the standard email/password sign-in method. Here's how to modify your existing code:
Step 1: Set Up Username-to-Email Mapping
First, you'll need to store a mapping of usernames to their corresponding emails somewhere in Firebase (we'll use Firestore here as an example). Make sure when users register, you save a document in a collection (e.g., usernames) where the document ID is the username, and the data includes the associated email.
Example registration snippet (for context):
// When registering a user const registerUser = (username, email, password) => { firebase.auth().createUserWithEmailAndPassword(email, password) .then(() => { // Save username -> email mapping to Firestore firebase.firestore().collection('usernames').doc(username).set({ email }); }); };
Step 2: Modify Your Login Function
Update your signinUserInFirebase function to first fetch the email from Firestore using the provided username, then proceed with the standard email/password sign-in:
export const signinUserInFirebase = (user, history) => (dispatch) => { dispatch({ type: LOGIN_USER }); console.log('data', user.username, user.password); // Now using username instead of email // 1. Look up the email associated with the username in Firestore firebase.firestore().collection('usernames').doc(user.username).get() .then(doc => { if (!doc.exists) { // Handle case where username doesn't exist throw new Error('Username not found'); } const userEmail = doc.data().email; // 2. Use the retrieved email to sign in return firebase.auth().signInWithEmailAndPassword(userEmail, user.password); }) .then((authUser) => { localStorage.setItem("user_id", authUser.user.uid); // Use actual user UID instead of hardcoded value dispatch({ type: LOGIN_USER_SUCCESS, payload: localStorage.getItem('user_id') }); history.push('/'); NotificationManager.success('User Login Successfully!'); }) .catch((error) => { dispatch({ type: LOGIN_USER_FAILURE }); NotificationManager.error(error.message); }); };
Key Notes & Improvements
- Security Rules: Don't forget to set up Firestore security rules to protect the
usernamescollection. For example, allow read access to everyone (since users need to look up usernames to log in), but restrict write access only to authenticated users creating their own username mapping:rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /usernames/{username} { allow read: if true; allow write: if request.auth != null && request.resource.data.email == request.auth.token.email; } } } - Unique Usernames: During registration, add a check to ensure the username is unique before creating the Firestore document to avoid conflicts.
- User UID: Instead of storing a hardcoded
"user-id"in localStorage, use the actual user UID fromauthUser.user.uid—this is unique per user and provided natively by Firebase Auth.
内容的提问来源于stack exchange,提问作者Shweta

