Почему Firebase считает, что ключ содержит . при установке нового значения?

#java #android #firebase #firebase-realtime-database #firebase-authentication

#java #Android #firebase #firebase-realtime-database #firebase-аутентификация

Вопрос:

Я пытаюсь вставить объект в Firebase, используя точный метод, описанный в руководствах Android-quickstart. Однако, когда я пытаюсь добавить нового пользователя с ключом uid , он выдает исключение:

 com.google.firebase.database.DatabaseException: Invalid key: . Keys must not contain '/', '.', '#', '$', '[', or ']'
        at com.google.firebase.database.core.utilities.Validation.validateWritableKey(com.google.firebase:firebase-database@@16.1.0:120)
        at com.google.firebase.database.core.utilities.Validation.validateWritableObject(com.google.firebase:firebase-database@@16.1.0:103)
        at com.google.firebase.database.core.utilities.Validation.validateWritableObject(com.google.firebase:firebase-database@@16.1.0:104)
        at com.google.firebase.database.DatabaseReference.setValueInternal(com.google.firebase:firebase-database@@16.1.0:293)
        at com.google.firebase.database.DatabaseReference.setValue(com.google.firebase:firebase-database@@16.1.0:166)
        ....
  

Код, выполняемый непосредственно перед этим, является:

 /* FirebaseUser is created with emailAndPassword just before this  and the
 * uid is retrieved from that new user.
 */
DatabaseReference db = FirebaseDatabase.getInstance().getReference();
db = db.child("users");
db = db.child(uid);
Log.d(TAG, "Attempting to insert user at"   uid );
Log.d(TAG, db.toString());
db.setValue(user).addOnCompleteListener(new OnCompleteListener<Void>() {
    @Override
    public void onComplete(@NonNull Task<Void> task) {
        if (task.isSuccessful()) {
            Log.d(TAG, "User created at "   uid);
        } else {
            Log.w(TAG, task.getException());
        }
    }
});
  

И вывод непосредственно перед возникновением исключения является:

 D/FirebaseAuth: Notifying id token listeners about user ( gDGy7BIGvQWjnQ7yZVCsdkIbAzx1 ).
D/SignUpActivity: Attempting to insert user at gDGy7BIGvQWjnQ7yZVCsdkIbAzx1
D/SignUpActivity: https://my-app.firebaseio.com/users/gDGy7BIGvQWjnQ7yZVCsdkIbAzx1
D/FirebaseAuth: Notifying auth state listeners about user ( gDGy7BIGvQWjnQ7yZVCsdkIbAzx1 ).
  

uid Из FirebaseUser явно нет никаких запрещенных символов, поэтому я не уверен, откуда берется это исключение.

Редактировать: user — это пользовательский объект с инициализированными полями email и username и несколькими другими неинициализированными полями (имя и местоположение), которые еще не были реализованы. Эта setValue() операция выполнялась на предыдущей итерации кода. В текущей итерации User также реализует Parcelable, чтобы пользователи могли передаваться между действиями.

Объявление текущего пользователя:

 public class User implements Parcelable {
    private String username;
    private String email;
    private String name;
    private Location location;

    public User() {}
        public User(String username, String email) {
        this.username = username;
        this.email = email;
    }

    protected User(Parcel in) {
        username = in.readString();
        email = in.readString();
        name = in.readString();
        location = in.readParcelable(Location.class.getClassLoader());
    }

    public static final Creator<User> CREATOR = new Creator<User>() { ... };

        public User(String username, String email) {
        this.username = username;
        this.email = email;
    }

    protected User(Parcel in) {
        username = in.readString();
        email = in.readString();
        name = in.readString();
        location = in.readParcelable(Location.class.getClassLoader());
    }
  

Комментарии:

1. что user содержит?

2. В какой строке кода указывается эта ошибка? Пожалуйста, ответьте с помощью @AlexMamo

3. @PeterHaddad user — это пользовательский объект, который содержит две строки для электронной почты пользователя и имени пользователя.

4. @AlexMamo Исключение возникает во время выполнения db.setValue()

5. @tchell Вы используете setValue() также в другой части своего кода?

Ответ №1:

Это может стать ясно из моей последней правки, но, похоже, что проблема заключается в реализации Parcelable и попытке чтения / записи неинициализированных полей. Если я удалю неинициализированные поля из распределяемой реализации, setValue() будет работать как ожидалось.

     protected User(Parcel in) {
        username = in.readString();
        email = in.readString();
        //name = in.readString();
        //location = in.readParcelable(Location.class.getClassLoader());
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(username);
        dest.writeString(email);
        //dest.writeString(name);
        //location.writeToParcel(dest, flags);
    }