How can I track the current number of viewers of an item?

风流意气都作罢 提交于 2019-12-13 06:26:54

问题


I have an iPhone app, where I want to show how many people are currently viewing an item as such:

I'm doing that by running this transaction when people enter a view (Rubymotion code below, but functions exactly like the Firebase iOS SDK):

listing_reference[:listings][self.id][:viewing_amount].transaction do |data|
  data.value = data.value.to_i + 1
  FTransactionResult.successWithValue(data)
end

And when they exit the view:

listing_reference[:listings][self.id][:viewing_amount].transaction do |data|
  data.value = data.value.to_i + -
  FTransactionResult.successWithValue(data)
end

It works fine most of the time, but sometimes things go wrong. The app crashes, people loose connectivity or similar things.

I've been looking at "onDisconnect" to solve this - https://firebase.google.com/docs/reference/ios/firebasedatabase/interface_f_i_r_database_reference#method-detail - but from what I can see, there's no "inDisconnectRunTransaction".

How can I make sure that the viewing amount on the listing gets decremented no matter what?


回答1:


A Firebase Database transaction runs as a compare-and-set operation: given the current value of a node, your code specifies the new value. This requires at least one round-trip between the client and server, which means that it is inherently unsuitable for onDisconnect() operations.

The onDisconnect() handler is instead a simple set() operation: you specify when you attach the handler, what write operation you want to happen when the servers detects that the client has disconnected (either cleanly or as in your problem case involuntarily).

The solution is (as is often the case with NoSQL databases) to use a data model that deals with the situation gracefully. In your case it seems most natural to not store the count of viewers, but instead the uid of each viewer:

itemViewers
  $itemId
    uid_1: true
    uid_2: true
    uid_3: true

Now you can get the number of viewers with a simple value listener:

ref.child('itemViewers').child(itemId).on('value', function(snapshot) {
  console.log(snapshot.numChildren());
});

And use the following onDisconnect() to clean up:

ref.child('itemViewers').child(itemId).child(authData.uid).remove();

Both code snippets are in JavaScript syntax, because I only noticed you're using Swift after typing them.



来源:https://stackoverflow.com/questions/37403251/how-can-i-track-the-current-number-of-viewers-of-an-item

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!