Firebase注册用户时添加含子节点的Scores节点实现疑问
Hey Robert, let's get this sorted out for you! When creating a user with Firebase Auth, you just need to extend the workflow to write the additional user details (including the nested Scores node) to the Realtime Database right after a successful registration. Here's a step-by-step solution:
1. Basic Registration + Database Write Workflow
First, we'll use Firebase Auth's createUserWithEmailAndPassword method, then in the success callback, we'll construct the full user object and write it to your Users node.
Option 1: Using HashMaps (Flexible for One-Off Writes)
This approach is great if you don't want to create dedicated model classes yet:
// Get references to Firebase Auth and Database FirebaseAuth mAuth = FirebaseAuth.getInstance(); FirebaseDatabase mDatabase = FirebaseDatabase.getInstance(); DatabaseReference usersRef = mDatabase.getReference("Users"); // User registration logic (replace with actual user input) String email = "example@domain.com"; String password = "userPassword123"; mAuth.createUserWithEmailAndPassword(email, password) .addOnCompleteListener(task -> { if (task.isSuccessful()) { // Get the newly created user's UID FirebaseUser currentUser = mAuth.getCurrentUser(); if (currentUser != null) { String uid = currentUser.getUid(); // Build the main user data HashMap<String, Object> userData = new HashMap<>(); userData.put("Admin", false); userData.put("Email", email); userData.put("Nickname", "Anonymous"); userData.put("Picture", "https://firebasestorage.googleapis.com/v0/b/cul..."); // Replace with your default URL // Build the nested Scores node HashMap<String, Object> scoresData = new HashMap<>(); scoresData.put("Arts", 0); scoresData.put("Classical music", 0); scoresData.put("Literature", 0); userData.put("Scores", scoresData); // Write the data to Firebase Database usersRef.child(uid).setValue(userData) .addOnSuccessListener(aVoid -> { Toast.makeText(getApplicationContext(), "Registration complete!", Toast.LENGTH_SHORT).show(); }) .addOnFailureListener(e -> { Log.e("Firebase", "Failed to save user data", e); }); } } else { // Handle registration failure (e.g., email already exists) Log.e("Firebase Auth", "Registration failed", task.getException()); } });
Option 2: Using Model Classes (Cleaner for Scalable Apps)
For a more structured approach, create model classes that mirror your database structure. This makes it easier to manage and update user data later.
Step 2a: Create the Model Classes
import com.google.firebase.database.PropertyName; public class User { private boolean Admin; private String Email; private String Nickname; private String Picture; private Scores Scores; // Empty constructor is REQUIRED for Firebase deserialization public User() {} public User(boolean admin, String email, String nickname, String picture, Scores scores) { Admin = admin; Email = email; Nickname = nickname; Picture = picture; Scores = scores; } // Getters and Setters public boolean isAdmin() { return Admin; } public void setAdmin(boolean admin) { Admin = admin; } public String getEmail() { return Email; } public void setEmail(String email) { Email = email; } public String getNickname() { return Nickname; } public void setNickname(String nickname) { Nickname = nickname; } public String getPicture() { return Picture; } public void setPicture(String picture) { Picture = picture; } public Scores getScores() { return Scores; } public void setScores(Scores scores) { Scores = scores; } // Nested Scores class public static class Scores { private int Arts; @PropertyName("Classical music") // Maps variable name to database key with space private int ClassicalMusic; private int Literature; public Scores() {} public Scores(int arts, int classicalMusic, int literature) { Arts = arts; ClassicalMusic = classicalMusic; Literature = literature; } // Getters and Setters public int getArts() { return Arts; } public void setArts(int arts) { Arts = arts; } @PropertyName("Classical music") public int getClassicalMusic() { return ClassicalMusic; } @PropertyName("Classical music") public void setClassicalMusic(int classicalMusic) { ClassicalMusic = classicalMusic; } public int getLiterature() { return Literature; } public void setLiterature(int literature) { Literature = literature; } } }
Step 2b: Use the Model Class in Registration
FirebaseAuth mAuth = FirebaseAuth.getInstance(); FirebaseDatabase mDatabase = FirebaseDatabase.getInstance(); DatabaseReference usersRef = mDatabase.getReference("Users"); String email = "example@domain.com"; String password = "userPassword123"; mAuth.createUserWithEmailAndPassword(email, password) .addOnCompleteListener(task -> { if (task.isSuccessful()) { FirebaseUser currentUser = mAuth.getCurrentUser(); if (currentUser != null) { String uid = currentUser.getUid(); // Create the Scores object with initial 0 values User.Scores initialScores = new User.Scores(0, 0, 0); // Create the full User object User newUser = new User( false, email, "Anonymous", "https://firebasestorage.googleapis.com/v0/b/cul...", initialScores ); // Write to database usersRef.child(uid).setValue(newUser) .addOnSuccessListener(aVoid -> { Toast.makeText(getApplicationContext(), "User registered successfully!", Toast.LENGTH_SHORT).show(); }) .addOnFailureListener(e -> { Log.e("Firebase DB", "Failed to save user data", e); }); } } else { Log.e("Firebase Auth", "Registration failed", task.getException()); } });
2. Critical Database Rule Setup
Make sure your Firebase Realtime Database rules allow authenticated users to write their own data. Go to your Firebase Console > Database > Rules and update them to something like:
{ "rules": { "Users": { "$uid": { ".write": "$uid === auth.uid", ".read": "$uid === auth.uid" } } } }
This ensures only the logged-in user can modify their own data, keeping your database secure.
3. Key Notes
- Always handle failure callbacks for both Auth and Database operations to catch errors like network issues or invalid permissions.
- If you're using Firebase Storage for profile pictures, you can upload the image first, get its download URL, then include it in the user data write.
- The empty constructors in the model classes are mandatory—Firebase uses them to deserialize data from the database.
内容的提问来源于stack exchange,提问作者Robert Pal

