Tôi đang làm việc trên một ứng dụng thực hiện điều gì đó tương tự như star count on a blog post example được đưa ra trong tài liệu Firebase và tôi có câu hỏi về thiết kế của hệ thống bỏ phiếu và có sử dụng hay không.Thiết kế phù hợp của hệ thống gắn dấu sao/thích trong Firebase: Tôi có nên sử dụng giao dịch không?
Từ ví dụ này, các dữ liệu cho một bài trông như thế này:
postid {
// some data here about the post, author, id, etc,
starCount : <an integer count of the stars>,
stars : {
<user who starred> : true,
<user who starred> : true,
// ... and so on, basically a list of all the users who starred the post
}
}
Các tài liệu sử dụng một giao dịch để cập nhật các sao đếm:
private void onStarClicked(DatabaseReference postRef) {
postRef.runTransaction(new Transaction.Handler() {
@Override
public Transaction.Result doTransaction(MutableData mutableData) {
Post p = mutableData.getValue(Post.class);
if (p == null) {
return Transaction.success(mutableData);
}
if (p.stars.containsKey(getUid())) {
// Unstar the post and remove self from stars
p.starCount = p.starCount - 1;
p.stars.remove(getUid());
} else {
// Star the post and add self to stars
p.starCount = p.starCount + 1;
p.stars.put(getUid(), true);
}
// Set value and report transaction success
mutableData.setValue(p);
return Transaction.success(mutableData);
}
@Override
public void onComplete(DatabaseError databaseError, boolean b,
DataSnapshot dataSnapshot) {
// Transaction completed
Log.d(TAG, "postTransaction:onComplete:" + databaseError);
}
});
}
Bởi vì việc sử dụng một giao dịch cả số starCount
và stars
dường như cần là một phần của cùng một đối tượng. Tại sao? Bởi vì tôi muốn sử dụng cả một giao dịch và đảm bảo tính tự động. Các tùy chọn khác để đảm bảo tính tự động là cập nhật đa đường dẫn, nhưng như được ghi chú here in the comments bạn không thể sử dụng cập nhật đa đường dẫn với các hiệu ứng chuyển tiếp. Bạn có quyền truy cập vào mutableData
(trong trường hợp này là đối tượng bài đăng) và đó là nó.
SO nếu starCount
và stars
phải được lưu trữ ở cùng một vị trí, Tôi không hiểu điểm của starCount. Bất cứ khi nào bạn nhận được một đối tượng bài đăng, nó sẽ bao gồm stars
, danh sách những người đã gắn dấu sao nó. Tại sao không xóa hoàn toàn starCount và chỉ nhận được kích thước của danh sách sao? Có điều gì đó không thực hiện về điều này?
Trong trường hợp này, gắn dấu sao/bỏ gắn dấu sao gì đó sẽ giống như p.stars.put(getUid(), true);
và p.stars.remove(getUid());
. Nếu tôi đã làm điều đó, tôi không thấy sự cần thiết cho một giao dịch, bởi vì tôi không còn có nhiều người dùng cập nhật một đối tượng "phản đối". Tôi có thể sử dụng giao dịch cho tuyên bố p.stars.put(getUid(), true);
, nhưng dường như không chắc với tôi rằng cùng một người dùng cố gắng gắn dấu sao/bỏ gắn dấu sao từ hai thiết bị khác nhau và thậm chí nếu họ làm như vậy, nó sẽ không bị ảnh hưởng nhiều đến mức tôi có thể nói.
Vì vậy, tôi thiếu gì ở đây? Tại sao sử dụng giao dịch tại đây và lợi ích nào lưu trữ và theo dõi theo cách thủ công starCount thêm? Tôi có thể thấy một lợi ích hiệu suất lưu trữ danh sách người dùng stars
ở nơi khác trong cơ sở dữ liệu, như được hiển thị trong this example, nhưng sau đó giao dịch sẽ không hoạt động.
Bất kỳ thông tin chi tiết nào sẽ được đánh giá cao và cảm ơn bạn!