I am working on an application that does something similar to the number of stars in the blog example given in the Firebase documentation, and I have a question about the design of the polling system and whether to use it.
In the example, the data for the message is as follows:
postid {
Documents use a transaction to update the number of stars:
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); } }); }
Due to the use of the transaction, both the starCount and stars tags seem to be part of the same object. What for? Because I want to use both transaction and self-confidence. Another option for providing automation is a multi-path update, but as noted here in the comments , you cannot use multi-path updates with transitions. You have access to mutableData (in this case post post) and what it is.
SO, if starCount and stars should be stored in the same place, I do not understand the point of starCount . Whenever you get a post object, it will include stars , a list of everyone who shot it. Why not remove starCount entirely and just get the size of the list of stars ? Is there anything not in this regard?
In this case, in the main / non- p.stars.put(getUid(), true); something will be something like p.stars.put(getUid(), true); and p.stars.remove(getUid()); . If I did this, I donβt see the need for a transaction, because I no longer have several users updating the counter object. I could use a transaction for the p.stars.put(getUid(), true); statement p.stars.put(getUid(), true); , but it seems unlikely to me that the same user who is trying to display / remove something from two different devices, and even if they did, it would not be a disaster as long as I can say.
So what am I missing here? Why use transactions here and what advantage does manual tracking of starCount add retain? I could see the performance benefits by storing the list of stars users elsewhere in the database, as shown in this example , but then the transaction would not work.
Any insight would be appreciated and thanks!