webentwicklung-frage-antwort-db.com.de

Firebase Android: Benutzername eindeutig machen

Parse wird Ende des Jahres heruntergefahren, daher habe ich mich für die Verwendung von Firebase entschieden. Ich muss einen Registrierungsprozess mit 3 Feldern implementieren: E-Mail, Benutzername, Passwort (E-Mail & Benutzername muss für meine App eindeutig sein).

Da Firebase keine einfache Möglichkeit bietet, Benutzernamen wie Parse zu verwalten, habe ich beschlossen, nur die E-Mail-/Passwort-Registrierung zu verwenden und einige zusätzliche Daten wie den Benutzernamen zu speichern. Hier ist meine Benutzerdatenstruktur:

app : {
    users: {
       "some-user-uid": {
            email: "[email protected]"
            username: "myname"
       }
    }
}

Ich möchte den Benutzernamen jedoch eindeutig machen und überprüfen, bevor ich ein Konto eröffne. Das sind meine Regeln:

{
    "rules": {
        ".read": true,
        ".write": true,
        "users": {
            "$uid": {
                ".write": "auth !== null && auth.uid === $uid",
                ".read": "auth !== null && auth.provider === 'password'",
                "username": {".validate": "!root.child('users').child(newData.child('username').val()).exists()"}
            }
        }
   }
}

Vielen Dank für Ihre Hilfe

31
FloGz

Ein Teil der Antwort besteht darin, einen Index der Benutzernamen zu speichern, gegen den Sie in Ihren Sicherheitsregeln prüfen:

app : {
    users: {
       "some-user-uid": {
            email: "[email protected]"
            username: "myname"
       }
    },
    usernames: {
        "myname": "some-user-uid"
    }
}

Daher ordnet der Knoten usernames einer UID einen Benutzernamen zu. Es lautet im Wesentlichen "Benutzername 'meinname' gehört 'some-user-uid'".

Mit dieser Datenstruktur können Ihre Sicherheitsregeln prüfen, ob für einen bestimmten Benutzernamen bereits ein Eintrag vorhanden ist:

"users": {
  "$uid": {
    ".write": "auth !== null && auth.uid === $uid",
    ".read": "auth !== null && auth.provider === 'password'",
    "username": {
      ".validate": "
        !root.child('usernames').child(newData.val()).exists() ||
        root.child('usernames').child(newData.val()).val() == $uid"
    }
  }
}

Dies bestätigt, dass der Benutzername noch von niemandem beansprucht wird OR vom aktuellen Benutzer.

48

Speichern Sie Benutzernamen wie von Frank vorgeschlagen. Wenn Sie jedoch Benutzernamen speichern, verwenden Sie die Funktion runTransaction in Firebase, um sicherzustellen, dass der Benutzername nicht verwendet wird. Diese Funktion wird von Firebase als atomare Operation garantiert, sodass Sie sicher sein können, dass keine Kollisionen auftreten

firebaseRef.child("usernames").child(username).runTransaction(new Transaction.Handler() {
    @Override
    public Transaction.Result doTransaction(MutableData mutableData) {
        if (mutableData.getValue() == null) {
            mutableData.setValue(authData.getUid());
            return Transaction.success(mutableData);
        }

        return Transaction.abort();
    }

    @Override
    public void onComplete(FirebaseError firebaseError, boolean commited, DataSnapshot dataSnapshot) {
        if (commited) {
            // username saved
        } else {
            // username exists
        }
    }
});
5
Viven