问题
I want to append a String to my List on the Firebase Realtime Database. (My code already works but there is a problem)
So the Database looks like this:
message:
0: "some string"
1: "another string"
2: "some string"
But I think the problem with this code would be, that if somebody reads the numbers of messages and then wants to write a message there would be a problem, when another user writes a message in the mean time (because the number of messages would change).
FirebaseDatabase database = FirebaseDatabase.getInstance();
final DatabaseReference myRef = database.getReference("message");
myRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
myRef.child(
String.valueOf(dataSnapshot.getChildrenCount())
).setValue("SOME STRING");
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
回答1:
Trying to use sequential numeric indexes (also often referred to as array indexes or auto-increment values) in a multi-user Firebase is an anti-pattern for a few reasons.
As you've already noted yourself, there's a chance of users overwriting each other's data. This is fixable however by using a transaction, which is the way to go if you need to property a value based on its existing value. The reference documentation for the JavaScript DatabaseReference.transaction method have this example that is pretty much what you need:
// Increment Ada's rank by 1. var adaRankRef = firebase.database().ref('users/ada/rank'); adaRankRef.transaction(function(currentRank) { // If users/ada/rank has never been set, currentRank will be `null`. return currentRank + 1; });
The syntax in Android is slightly more involved, but would work the same.
While a transaction works, this means that the application will only work when the user is connected to the server. When they're offline, the transaction will fail.
For these reasons Firebase apps typically use a different mechanism to generate their keys. The built-in push() method of the API generates a unique, always-incrementing key. While this key is not as readable as your sequential, numeric keys, they do address both of the above problems without the need for you to write more code for it yourself. With push()
adding a message becomes as simple as:
final DatabaseReference myRef = database.getReference("message");
myRef.push().setValue("SOME STRING");
Note that this topic has been covered quite a bit already, so I recommend also checking out:
- Best Practices: Arrays in Firebase
- The 2^120 Ways to Ensure Unique Identifiers
- How to create auto incremented key in Firebase?
- Auto-increment a value in Firebase (has the transaction code for Android)
- how do i auto increment a value in firebase
来源:https://stackoverflow.com/questions/54379558/append-a-string-to-a-list-on-firebase-realtime-database