Это мое правило базы данных:
{
"rules": {
"Users' Input History": {
"$uid": {
".read": "auth.uid == $uid",
".write": "auth.uid == $uid"
}
},
"Users' Vocabulary List": {
"$uid": {
".read": "auth.uid == $uid",
".write": "auth.uid == $uid"
}
}
}
}
Как видите, я пытаюсь предоставить права на чтение и запись тем, у кого есть аутентифицированный uid (пользователь). Каждый пользователь может видеть только свои собственные созданные значения в узле «$ uid» и не может видеть значения, отправленные другими пользователями. Однако при моделировании возникла ошибка: «Чтение» запрещено. Ниже приведен скриншот, когда я запустил симуляцию:
Ниже приведена структура узла базы данных:
{
"Users' Input History" : {
"TdtIwvAPewRr1l9HY67PfkLBPbn2" : {
"-M-eylUaQcCpoyTLwbhk" : "fate"
}
},
"Users' Vocabulary List" : {
"TdtIwvAPewRr1l9HY67PfkLBPbn2" : {
"-M-eyxRLoCpDftWQ4cDn" : "hardliner"
}
}
}
Обратите внимание, что значения (которые являются «судьбой») "и" hardliner ") были вручную добавлены в базу данных через консоль firebase, просто чтобы показать вам, как должна выглядеть моя база данных. Фактическая ситуация такова: когда я отправляю значение (например, «судьба») в базу данных через мое телефонное приложение, следующий фрагмент строк появляется в базе данных на долю секунды, но затем сразу же удаляется (или исчезает) автоматически :
"Users' Input History" : {
"TdtIwvAPewRr1l9HY67PfkLBPbn2" : {
"-M-eylUaQcCpoyTLwbhk" : "fate"
}
}
И то же самое происходит, когда я передаю значение "hardliner". Таким образом, получается, что, учитывая текущее правило базы данных, новые значения будут появляться, а затем быстро исчезать в моей базе данных, что делает мое правило базы данных бессмысленным.
Вот коды для аутентификации и отправки значений в базы данных.
Моя активность для входа в систему:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_google_sign_in);
(some uncritical codes omitted here)
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build();
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
mAuth = FirebaseAuth.getInstance();
}
@Override
public void onStart() {
super.onStart();
FirebaseUser currentUser = mAuth.getCurrentUser();
updateUI(currentUser);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
GoogleSignInApi.getSignInIntent(...);
if (requestCode == RC_SIGN_IN) {
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
try {
// Google Sign In was successful, authenticate with Firebase
GoogleSignInAccount account = task.getResult(ApiException.class);
firebaseAuthWithGoogle(account);
//The mDetailTextView will display the user's unique uid and the become the variable "username" which will later be used to push values into the database.
username = mDetailTextView.getText().toString();
} catch (ApiException e) {
Log.w(TAG, "Google sign in failed", e);
updateUI(null);
}
}
}
private void firebaseAuthWithGoogle(GoogleSignInAccount acct) {
Log.d(TAG, "firebaseAuthWithGoogle:" + acct.getId());
showProgressBar();
AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Log.d(TAG, "signInWithCredential:success");
FirebaseUser user = mAuth.getCurrentUser();
updateUI(user);
} else {
Log.w(TAG, "signInWithCredential:failure", task.getException());
Snackbar.make(findViewById(R.id.main_layout), "Authentication Failed.", Snackbar.LENGTH_SHORT).show();
updateUI(null);
}
hideProgressBar();
}
});
}
private void signIn() {
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
startActivityForResult(signInIntent, RC_SIGN_IN);
}
private void updateUI(FirebaseUser user) {
if (user != null) {
mDetailTextView.setText(getString(R.string.Firebase_status_fmt, user.getUid()));
} else {
mDetailTextView.setText(null);
}
}
Моя активность для отправки значений в базу данных:
public static DatabaseReference mRootReference = FirebaseDatabase.getInstance().getReference();
public static DatabaseReference mChildReferenceForInputHistory = mRootReference.child("Users' Input History");
public static DatabaseReference mChildReferenceForVocabularyList = mRootReference.child("Users' Vocabulary List");
searchKeyword = wordInputView.getText().toString();
Query query = mChildReferenceForInputHistory.child(username).orderByValue().equalTo(searchKeyword);
query.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot: dataSnapshot.getChildren()) {
snapshot.getRef().setValue(null);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
throw databaseError.toException();
}
});
mChildReferenceForInputHistory.child(username).push().setValue(searchKeyword);
mChildReferenceForInputHistory.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String previousChildKey) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
String value = snapshot.getValue(String.class);
}
}
@Override
public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
}
@Override
public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
Я пытался объяснить ситуацию как можно больше, но я понятия не имею, как начать точно определять причину и решать проблему. Кто-нибудь может помочь?