英文:
After creating a user with email and password with Android Firebase I cannot save additional information in a users collection
问题
创建用户使用createUserWithEmailAndPassword(email, password)
函数后,我尝试将已注册用户的附加信息保存在名为“users”的集合中。为此,我使用了DocumentReference
:
mAuth.createUserWithEmailAndPassword(email, password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
FirebaseUser fuser = FirebaseAuth.getInstance().getCurrentUser();
String idUser = fuser.getUid();
DocumentReference documentReference = fStore.collection("users").document(fuser.getUid());
Map<String, Object> user = new HashMap<>();
Log.d("data", "username: "+username + " telef: "+telefono);
user.put("username", username);
user.put("telefono", telefono);
documentReference.set(user).addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "User profile created");
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d(TAG, "can't create profile: "+e.toString());
}
});
FirebaseAuth.getInstance().signOut();
mProgressBar.dismiss();
Intent intent = new Intent(RegisterActivity.this, loginActivity.class);
startActivity(intent);
RegisterActivity.this.finish();
Toast.makeText(getApplicationContext(), "Registered ok!", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "can't register", Toast.LENGTH_LONG).show();
}
}
});
除了已实例化:
mAuth = FirebaseAuth.getInstance();
fStore = FirebaseFirestore.getInstance();
我还不得不添加以下内容:
private void initFirebase() {
FirebaseApp.initializeApp(this);
firebaseDatabase = FirebaseDatabase.getInstance();
firebaseDatabase.setPersistenceEnabled(true);
databaseReference = firebaseDatabase.getReference();
}
即使加入了上述内容,问题仍未解决。只有使用电子邮件和密码注册的用户。奇怪的是没有错误,似乎onSuccess
或onFailure
事件没有发生。Firebase控制台中的数据库规则如下:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth.uid != null;
}
}
}
基本上,这个规则表明用户必须经过身份验证才能读取/写入数据库。我的依赖项如下:
implementation 'com.google.firebase:firebase-auth:19.3.0'
implementation 'com.google.firebase:firebase-firestore:21.4.2'
implementation 'com.google.firebase:firebase-storage:19.1.1'
implementation 'com.google.firebase:firebase-database:18.0.1'
我应该使用firebase-firestore
和firebase-auth
,但我已经添加了firebase-database
和firebase-storage
以解决问题,但仍然没有效果。
提前感谢。
英文:
After creating a user using the firebaseAuth function createUserWithEmailAndPassword (email, password)
I am trying to save additional information of the users that are registered in a collection called "users". For that I use DocumentReference:
mAuth.createUserWithEmailAndPassword(email, password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
FirebaseUser fuser = FirebaseAuth.getInstance().getCurrentUser();
String idUser = fuser.getUid();
DocumentReference documentReference = fStore.collection("users").document(fuser.getUid());
Map<String, Object> user = new HashMap<>();
Log.d("data", "username: "+username + " telef: "+telefono);
user.put("username", username);
user.put("telefono", telefono);
documentReference.set(user).addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "User profile created");
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d(TAG, "can´t create profile: "+e.toString());
}
});
//sign out the user.. dont work.. any ideas?
FirebaseAuth.getInstance().signOut();
mProgressBar.dismiss();
//send the user to log in
Intent intent = new Intent(RegisterActivity.this, loginActivity.class);
//intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
RegisterActivity.this.finish();
Toast.makeText(getApplicationContext(), "Registered ok!", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(getApplicationContext(), "can´t register", Toast.LENGTH_LONG).show();
}
}
});
Apart from having instantiated:
mAuth = FirebaseAuth.getInstance();
fStore = FirebaseFirestore.getInstance();
I have also been forced to add the following:
private void initFirebase() {
FirebaseApp.initializeApp(this);
firebaseDatabase = FirebaseDatabase.getInstance();
firebaseDatabase.setPersistenceEnabled(true);
databaseReference = firebaseDatabase.getReference();
}
Not even with the latter it works. Only the user with email and password is registered. The strange thing is that there is no error, it seems that the onSuccess
or onFailure
event does not occur. The database rules in the firebase console are:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth.uid != null;
}
}
}
Basically this rule indicates that the user must be authenticated to be able to read / write to the database. My dependencies are:
implementation 'com.google.firebase:firebase-auth:19.3.0'
implementation 'com.google.firebase:firebase-firestore:21.4.2'
implementation 'com.google.firebase:firebase-storage:19.1.1'
implementation 'com.google.firebase:firebase-database:18.0.1'
I should use firebase-firestore and firebase-auth but I have added firebase-database and firebase-storage in order to solve the problem but nothing happens.
Thanks in advance.
答案1
得分: 1
你的代码在数据库写入之前登出了用户,因此写入将不会通过任何要求用户已登录的数据库规则。
documentReference.set(user)
是异步的,会立即返回,而实际的写入操作会在稍后进行。与此同时,你的代码立即执行了 FirebaseAuth.getInstance().signOut()
进行登出操作,这会删除用户的身份验证令牌,导致查询在没有任何凭据的情况下进行。
如果你需要在数据库写入后将用户登出,你应该将这个操作放在数据库回调代码内部。尽管我不太清楚为什么你会希望这样做。你可能应该考虑完全移除登出操作。
英文:
Your code is signing out the user before the database is written, so the write will fail any database rules that require the user to be signed in.
documentReference.set(user)
is asynchronous and returns immediately, before any work has been done. The database will be written some time later. Meanwhile, your code goes on to immediately execute a signout with FirebaseAuth.getInstance().signOut()
, which deletes the user's auth token, making the query happen without any credentials.
If you need the user to be signed out after writing the database, you should do that inside the database callback code. Though it's entirely clear to me why you would want that to happen. You should probably just remove the signout completely.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论