1
+ package id.ruangopini.data.repo.remote.firebase.firestore.analytics
2
+
3
+ import android.util.Log
4
+ import com.google.firebase.Timestamp
5
+ import com.google.firebase.firestore.FieldValue
6
+ import com.google.firebase.firestore.ktx.firestore
7
+ import com.google.firebase.ktx.Firebase
8
+ import id.ruangopini.data.model.Analytics
9
+ import id.ruangopini.data.model.CategoryAnalytics
10
+ import id.ruangopini.data.model.DiscussionAnalytics
11
+ import id.ruangopini.data.model.PostAnalytics
12
+ import id.ruangopini.data.repo.State
13
+ import id.ruangopini.utils.COLLECTION
14
+ import id.ruangopini.utils.DateFormat
15
+ import id.ruangopini.utils.Helpers
16
+ import id.ruangopini.utils.Helpers.formatDate
17
+ import kotlinx.coroutines.Dispatchers
18
+ import kotlinx.coroutines.ExperimentalCoroutinesApi
19
+ import kotlinx.coroutines.channels.awaitClose
20
+ import kotlinx.coroutines.flow.*
21
+ import kotlinx.coroutines.tasks.await
22
+
23
+ @ExperimentalCoroutinesApi
24
+ class FirestoreAnalyticsRepository : FirestoreAnalyticsDataStore {
25
+
26
+ private val instance = Firebase .firestore.collection(COLLECTION .ANALYTICS )
27
+
28
+ override fun updateDiscussion (category : String ): Flow <State <Boolean >> = flow<State <Boolean >> {
29
+ emit(State .loading())
30
+ val date = Timestamp .now().formatDate(DateFormat .SHORT )
31
+ val snapshot = instance.document(date ? : " " ).collection(COLLECTION .CATEGORY )
32
+ .document(category).update(" discussion" , FieldValue .increment(1 ))
33
+ snapshot.await()
34
+ emit(State .success(snapshot.isSuccessful))
35
+ }.catch {
36
+ emit(State .loading())
37
+ val mCategory = CategoryAnalytics (category, 1 , 0 )
38
+
39
+ val date = Timestamp .now().formatDate(DateFormat .SHORT )
40
+ val docSnap = instance.document(date ? : " " )
41
+ docSnap.set(Analytics ()).await()
42
+
43
+ val snapshot = docSnap.collection(COLLECTION .CATEGORY )
44
+ .document(category).set(mCategory)
45
+ snapshot.await()
46
+
47
+ if (snapshot.isSuccessful) emit(State .success(true ))
48
+ else {
49
+ Log .d(" TAG" , " updateDiscussion: failed = ${it.message} " )
50
+ emit(State .failed(it.message ? : " " ))
51
+ }
52
+ }.flowOn(Dispatchers .IO )
53
+
54
+ override fun updateJoinCategory (category : String , isJoin : Boolean ) = flow<State <Boolean >> {
55
+ emit(State .loading())
56
+ val date = Timestamp .now().formatDate(DateFormat .SHORT )
57
+ val snapshot = instance.document(date ? : " " ).collection(COLLECTION .CATEGORY )
58
+ .document(category).update(" join" , FieldValue .increment(if (isJoin) 1 else - 1 ))
59
+ snapshot.await()
60
+ emit(State .success(snapshot.isSuccessful))
61
+ }.catch {
62
+ emit(State .loading())
63
+ val mCategory = CategoryAnalytics (category, 0 , 1 )
64
+
65
+ val date = Timestamp .now().formatDate(DateFormat .SHORT )
66
+ val docSnap = instance.document(date ? : " " )
67
+ docSnap.set(Analytics ()).await()
68
+
69
+ val snapshot = docSnap.collection(COLLECTION .CATEGORY )
70
+ .document(category).set(mCategory)
71
+ snapshot.await()
72
+
73
+ if (snapshot.isSuccessful) emit(State .success(true ))
74
+ else {
75
+ Log .d(" TAG" , " updateJoinCategory: failed = ${it.message} " )
76
+ emit(State .failed(it.message ? : " " ))
77
+ }
78
+ }.flowOn(Dispatchers .IO )
79
+
80
+ override fun getAnotherPopular () = callbackFlow<State <List <CategoryAnalytics >>> {
81
+ trySend(State .loading()).isSuccess
82
+ instance.whereLessThan(" createdAt" , Timestamp .now())
83
+ .whereGreaterThan(" createdAt" , Helpers .getSevenDayAgo())
84
+ .addSnapshotListener { value, error ->
85
+ if (error != null ) {
86
+ trySend(State .failed(error.message ? : " " )).isSuccess
87
+ close(error)
88
+ return @addSnapshotListener
89
+ }
90
+ if (value != null && ! value.isEmpty) value.toObjects(Analytics ::class .java)
91
+ .forEach { data ->
92
+ instance.document(data.time ? : " " ).collection(COLLECTION .CATEGORY )
93
+ .addSnapshotListener { result, error ->
94
+ if (error != null ) {
95
+ trySend(State .failed(error.message ? : " " )).isSuccess
96
+ close(error)
97
+ }
98
+
99
+ val category = if (result != null && ! result.isEmpty)
100
+ result.toObjects(CategoryAnalytics ::class .java)
101
+ else emptyList()
102
+
103
+ trySend(State .success(category)).isSuccess
104
+ }
105
+ }
106
+ }
107
+ awaitClose()
108
+ }.catch {
109
+ emit(State .failed(it.message ? : " " ))
110
+ }.flowOn(Dispatchers .IO )
111
+
112
+ override fun updatePostDiscussion (discussionId : String ) = flow<State <Boolean >> {
113
+ emit(State .loading())
114
+ val date = Timestamp .now().formatDate(DateFormat .SHORT )
115
+ val snapshot = instance.document(date ? : " " ).collection(COLLECTION .DISCUSSION )
116
+ .document(discussionId).update(" post" , FieldValue .increment(1 ))
117
+ snapshot.await()
118
+ emit(State .success(snapshot.isSuccessful))
119
+ }.catch {
120
+ emit(State .loading())
121
+ val discussion = DiscussionAnalytics (0 , 0 , 1 )
122
+
123
+ val date = Timestamp .now().formatDate(DateFormat .SHORT )
124
+ val docSnap = instance.document(date ? : " " )
125
+ docSnap.set(Analytics ()).await()
126
+
127
+ val snapshot = docSnap.collection(COLLECTION .DISCUSSION )
128
+ .document(discussionId).set(discussion)
129
+ snapshot.await()
130
+
131
+ if (snapshot.isSuccessful) emit(State .success(true ))
132
+ else {
133
+ Log .d(" TAG" , " updatePostDiscussion: failed = ${it.message} " )
134
+ emit(State .failed(it.message ? : " " ))
135
+ }
136
+ }.flowOn(Dispatchers .IO )
137
+
138
+ override fun updateJoinDiscussion (discussionId : String , isJoin : Boolean ) =
139
+ flow<State <Boolean >> {
140
+ emit(State .loading())
141
+ val date = Timestamp .now().formatDate(DateFormat .SHORT )
142
+ val snapshot = instance.document(date ? : " " ).collection(COLLECTION .DISCUSSION )
143
+ .document(discussionId).update(" join" , FieldValue .increment(if (isJoin) 1 else - 1 ))
144
+ snapshot.await()
145
+ emit(State .success(snapshot.isSuccessful))
146
+ }.catch {
147
+ emit(State .loading())
148
+ val discussion = DiscussionAnalytics (1 , 0 , 0 )
149
+
150
+ val date = Timestamp .now().formatDate(DateFormat .SHORT )
151
+ val docSnap = instance.document(date ? : " " )
152
+ docSnap.set(Analytics ()).await()
153
+
154
+ val snapshot = docSnap.collection(COLLECTION .DISCUSSION )
155
+ .document(discussionId).set(discussion)
156
+ snapshot.await()
157
+
158
+ if (snapshot.isSuccessful) emit(State .success(true ))
159
+ else {
160
+ Log .d(" TAG" , " updateJoinDiscussion: failed = ${it.message} " )
161
+ emit(State .failed(it.message ? : " " ))
162
+ }
163
+ }.flowOn(Dispatchers .IO )
164
+
165
+ override fun updateCommentDiscussion (discussionId : String ) = flow<State <Boolean >> {
166
+ emit(State .loading())
167
+ val date = Timestamp .now().formatDate(DateFormat .SHORT )
168
+ val snapshot = instance.document(date ? : " " ).collection(COLLECTION .DISCUSSION )
169
+ .document(discussionId).update(" comment" , FieldValue .increment(1 ))
170
+ snapshot.await()
171
+ emit(State .success(snapshot.isSuccessful))
172
+ }.catch {
173
+ emit(State .loading())
174
+ val discussion = DiscussionAnalytics (0 , 1 , 0 )
175
+
176
+ val date = Timestamp .now().formatDate(DateFormat .SHORT )
177
+ val docSnap = instance.document(date ? : " " )
178
+ docSnap.set(Analytics ()).await()
179
+
180
+ val snapshot = docSnap.collection(COLLECTION .DISCUSSION )
181
+ .document(discussionId).set(discussion)
182
+ snapshot.await()
183
+
184
+ if (snapshot.isSuccessful) emit(State .success(true ))
185
+ else {
186
+ Log .d(" TAG" , " updateCommentDiscussion: failed = ${it.message} " )
187
+ emit(State .failed(it.message ? : " " ))
188
+ }
189
+ }.flowOn(Dispatchers .IO )
190
+
191
+ override fun updateCommentPost (postId : String ) = flow<State <Boolean >> {
192
+ emit(State .loading())
193
+ val date = Timestamp .now().formatDate(DateFormat .SHORT )
194
+ val snapshot = instance.document(date ? : " " ).collection(COLLECTION .POST )
195
+ .document(postId).update(" comment" , FieldValue .increment(1 ))
196
+ snapshot.await()
197
+ emit(State .success(snapshot.isSuccessful))
198
+ }.catch {
199
+ emit(State .loading())
200
+ val post = PostAnalytics (0 , 0 , 1 )
201
+
202
+ val date = Timestamp .now().formatDate(DateFormat .SHORT )
203
+ val docSnap = instance.document(date ? : " " )
204
+ docSnap.set(Analytics ()).await()
205
+
206
+ val snapshot = docSnap.collection(COLLECTION .POST )
207
+ .document(postId).set(post)
208
+ snapshot.await()
209
+ if (snapshot.isSuccessful) emit(State .success(true ))
210
+ else {
211
+ Log .d(" TAG" , " updateCommentPost: failed = ${it.message} " )
212
+ emit(State .failed(it.message ? : " " ))
213
+ }
214
+ }.flowOn(Dispatchers .IO )
215
+
216
+ override fun updateVoteUpPost (postId : String , vote : Int ) = flow<State <Boolean >> {
217
+ emit(State .loading())
218
+ val date = Timestamp .now().formatDate(DateFormat .SHORT )
219
+ val snapshot = instance.document(date ? : " " ).collection(COLLECTION .POST )
220
+ .document(postId).update(" voteUp" , FieldValue .increment(vote.toLong()))
221
+ snapshot.await()
222
+ emit(State .success(snapshot.isSuccessful))
223
+ }.catch {
224
+ emit(State .loading())
225
+ val post = PostAnalytics (1 , 0 , 0 )
226
+
227
+ val date = Timestamp .now().formatDate(DateFormat .SHORT )
228
+ val docSnap = instance.document(date ? : " " )
229
+ docSnap.set(Analytics ()).await()
230
+
231
+ val snapshot = docSnap.collection(COLLECTION .POST )
232
+ .document(postId).set(post)
233
+ snapshot.await()
234
+ if (snapshot.isSuccessful) emit(State .success(true ))
235
+ else {
236
+ Log .d(" TAG" , " updateVoteUpPost: failed = ${it.message} " )
237
+ emit(State .failed(it.message ? : " " ))
238
+ }
239
+ }.flowOn(Dispatchers .IO )
240
+
241
+ override fun updateVoteDownPost (postId : String , vote : Int ) = flow<State <Boolean >> {
242
+ emit(State .loading())
243
+ val date = Timestamp .now().formatDate(DateFormat .SHORT )
244
+ val snapshot = instance.document(date ? : " " ).collection(COLLECTION .POST )
245
+ .document(postId).update(" voteDown" , FieldValue .increment(vote.toLong()))
246
+ snapshot.await()
247
+ emit(State .success(snapshot.isSuccessful))
248
+ }.catch {
249
+ emit(State .loading())
250
+ val post = PostAnalytics (0 , 1 , 0 )
251
+
252
+ val date = Timestamp .now().formatDate(DateFormat .SHORT )
253
+ val docSnap = instance.document(date ? : " " )
254
+ docSnap.set(Analytics ()).await()
255
+
256
+ val snapshot = docSnap.collection(COLLECTION .POST )
257
+ .document(postId).set(post)
258
+ snapshot.await()
259
+ if (snapshot.isSuccessful) emit(State .success(true ))
260
+ else {
261
+ Log .d(" TAG" , " updateVoteDownPost: failed = ${it.message} " )
262
+ emit(State .failed(it.message ? : " " ))
263
+ }
264
+ }.flowOn(Dispatchers .IO )
265
+ }
0 commit comments