-
Notifications
You must be signed in to change notification settings - Fork 398
/
SolutionCounters.kt
75 lines (62 loc) · 2.44 KB
/
SolutionCounters.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package com.google.example.firestore.kotlin
import com.google.android.gms.tasks.Task
import com.google.android.gms.tasks.Tasks
import com.google.firebase.firestore.DocumentReference
import com.google.firebase.firestore.FirebaseFirestore
/**
* https://firebase.google.com/docs/firestore/solutions/counters
*/
class SolutionCounters(val db: FirebaseFirestore) {
// [START counter_classes]
// counters/${ID}
data class Counter(var numShards: Int)
// counters/${ID}/shards/${NUM}
data class Shard(var count: Int)
// [END counter_classes]
// [START create_counter]
fun createCounter(ref: DocumentReference, numShards: Int): Task<Void> {
// Initialize the counter document, then initialize each shard.
return ref.set(Counter(numShards))
.continueWithTask { task ->
if (!task.isSuccessful) {
throw task.exception!!
}
val tasks = arrayListOf<Task<Void>>()
// Initialize each shard with count=0
for (i in 0 until numShards) {
val makeShard = ref.collection("shards")
.document(i.toString())
.set(Shard(0))
tasks.add(makeShard)
}
Tasks.whenAll(tasks)
}
}
// [END create_counter]
// [START increment_counter]
fun incrementCounter(ref: DocumentReference, numShards: Int): Task<Void> {
val shardId = Math.floor(Math.random() * numShards).toInt()
val shardRef = ref.collection("shards").document(shardId.toString())
return db.runTransaction { transaction ->
val shard = transaction.get(shardRef).toObject(Shard::class.java)
shard!!.count += 1
transaction.set(shardRef, shard!!)
null
}
}
// [END increment_counter]
// [START get_count]
fun getCount(ref: DocumentReference): Task<Int> {
// Sum the count of each shard in the subcollection
return ref.collection("shards").get()
.continueWith { task ->
var count = 0
for (snap in task.result!!) {
val shard = snap.toObject(Shard::class.java)
count += shard.count
}
count
}
}
// [END get_count]
}