@@ -14,7 +14,13 @@ import com.mparticle.commerce.Product
1414import com.mparticle.consent.ConsentState
1515import com.mparticle.internal.Logger
1616import com.mparticle.internal.MPUtility
17- import com.mparticle.kits.KitIntegration.*
17+ import com.mparticle.kits.KitIntegration.ActivityListener
18+ import com.mparticle.kits.KitIntegration.ApplicationStateListener
19+ import com.mparticle.kits.KitIntegration.AttributeListener
20+ import com.mparticle.kits.KitIntegration.CommerceListener
21+ import com.mparticle.kits.KitIntegration.EventListener
22+ import com.mparticle.kits.KitIntegration.PushListener
23+ import com.mparticle.kits.KitIntegration.UserAttributeListener
1824import com.singular.sdk.Singular
1925import com.singular.sdk.SingularConfig
2026import com.singular.sdk.internal.SingularLog
@@ -26,6 +32,8 @@ open class SingularKit : KitIntegration(), ActivityListener, EventListener,
2632 PushListener , CommerceListener , ApplicationStateListener , UserAttributeListener ,
2733 AttributeListener {
2834 private val logger = SingularLog .getLogger(Singular ::class .java.simpleName)
35+ private var isInitialized = false
36+ private var deviceToken: String? = null
2937
3038 // endregion
3139 // region Kit Integration Implementation
@@ -36,16 +44,13 @@ open class SingularKit : KitIntegration(), ActivityListener, EventListener,
3644 // Returning the reporting message to state that the method was successful and
3745 // Preventing from the mParticle Kit to retry to activate to method.
3846 val messages: MutableList <ReportingMessage > = ArrayList ()
39- if (Singular .init (context, buildSingularConfig(settings))) {
40- singularSettings = settings
41- messages.add(
42- ReportingMessage (
43- this ,
44- ReportingMessage .MessageType .APP_STATE_TRANSITION ,
45- System .currentTimeMillis(), null
46- )
47+ messages.add(
48+ ReportingMessage (
49+ this ,
50+ ReportingMessage .MessageType .APP_STATE_TRANSITION ,
51+ System .currentTimeMillis(), null
4752 )
48- }
53+ )
4954 return messages
5055 }
5156
@@ -120,8 +125,10 @@ open class SingularKit : KitIntegration(), ActivityListener, EventListener,
120125 }
121126
122127 // region Unimplemented (Empty Methods)
123- override fun onActivityCreated (activity : Activity , bundle : Bundle ? ): List <ReportingMessage > =
124- emptyList()
128+ override fun onActivityCreated (activity : Activity , bundle : Bundle ? ): List <ReportingMessage > {
129+ initializeSingular()
130+ return emptyList()
131+ }
125132
126133 override fun onActivityStarted (activity : Activity ): List <ReportingMessage > = emptyList()
127134
@@ -140,21 +147,23 @@ open class SingularKit : KitIntegration(), ActivityListener, EventListener,
140147 // region Event Listener Implementation
141148 override fun logEvent (mpEvent : MPEvent ): List <ReportingMessage >? {
142149 val messages: MutableList <ReportingMessage > = ArrayList ()
143- val eventName = mpEvent.eventName
144- val eventInfo = mpEvent.customAttributes
150+ executeIfSingularInitialized({
151+ val eventName = mpEvent.eventName
152+ val eventInfo = mpEvent.customAttributes
145153
146- // Logging the event with the Singular API
147- val eventStatus: Boolean = if (! eventInfo.isNullOrEmpty()) {
148- Singular .eventJSON(eventName, JSONObject (eventInfo))
149- } else {
150- Singular .event(eventName)
151- }
154+ // Logging the event with the Singular API
155+ val eventStatus: Boolean = if (! eventInfo.isNullOrEmpty()) {
156+ Singular .eventJSON(eventName, JSONObject (eventInfo))
157+ } else {
158+ Singular .event(eventName)
159+ }
152160
153- // If the Singular event logging was successful, return the message to the mParticle Kit
154- // So it won't retry the event
155- if (eventStatus) {
156- messages.add(ReportingMessage .fromEvent(this , mpEvent))
157- }
161+ // If the Singular event logging was successful, return the message to the mParticle Kit
162+ // So it won't retry the event
163+ if (eventStatus) {
164+ messages.add(ReportingMessage .fromEvent(this , mpEvent))
165+ }
166+ }, forceInitSingular = true , " logEvent" )
158167 return messages
159168 }
160169
@@ -178,12 +187,48 @@ open class SingularKit : KitIntegration(), ActivityListener, EventListener,
178187 // region Push Listener Implementation
179188 override fun onPushRegistration (deviceToken : String , senderId : String ): Boolean {
180189 // Saving the registration token to determine when the user uninstalls the app.
181- if (MPUtility .isFirebaseAvailable()) {
182- Singular .setFCMDeviceToken(deviceToken)
183- }
190+ this .deviceToken = deviceToken
191+ executeIfSingularInitialized({
192+ if (MPUtility .isFirebaseAvailable()) {
193+ Singular .setFCMDeviceToken(deviceToken)
194+ }
195+ }, forceInitSingular = false , " onPushRegistration" )
184196 return true
185197 }
186198
199+ private fun executeIfSingularInitialized (
200+ operation : () -> Unit ,
201+ forceInitSingular : Boolean = false,
202+ operationName : String
203+ ) {
204+ if (isInitialized) {
205+ operation.invoke()
206+ Logger .debug(" $operationName executed" )
207+ } else {
208+ if (forceInitSingular) {
209+ initializeSingular()
210+ executeIfSingularInitialized(operation, false , operationName)
211+ } else {
212+ Logger .debug(" $operationName can't be executed, Singular not initialized" )
213+ }
214+ }
215+ }
216+
217+ private fun initializeSingular () {
218+ if (! isInitialized) {
219+ if (Singular .init (context, buildSingularConfig(settings))) {
220+ currentUser?.id?.toString()?.let { Singular .setCustomUserId(it) }
221+ isInitialized = true
222+ singularSettings = settings
223+ deviceToken?.let { deviceToken ->
224+ if (MPUtility .isFirebaseAvailable()) {
225+ Singular .setFCMDeviceToken(deviceToken)
226+ }
227+ }
228+ }
229+ }
230+ }
231+
187232 // region Unimplemented (Empty Methods)
188233 override fun willHandlePushMessage (intent : Intent ): Boolean = false
189234
@@ -193,11 +238,15 @@ open class SingularKit : KitIntegration(), ActivityListener, EventListener,
193238 // endregion
194239 // region Commerce Listener Implementation
195240 override fun logEvent (commerceEvent : CommerceEvent ): List <ReportingMessage > {
196- return if (commerceEvent.productAction == Product .PURCHASE ) {
197- handlePurchaseEvents(commerceEvent)
198- } else {
199- handleNonPurchaseEvents(commerceEvent)
200- }
241+ var list = emptyList<ReportingMessage >()
242+ executeIfSingularInitialized(operation = {
243+ if (commerceEvent.productAction == Product .PURCHASE ) {
244+ list = handlePurchaseEvents(commerceEvent)
245+ } else {
246+ list = handleNonPurchaseEvents(commerceEvent)
247+ }
248+ }, forceInitSingular = true , " logEvent" )
249+ return list
201250 }
202251
203252 private fun handlePurchaseEvents (commerceEvent : CommerceEvent ): List <ReportingMessage > {
@@ -264,7 +313,11 @@ open class SingularKit : KitIntegration(), ActivityListener, EventListener,
264313 }
265314 }
266315 if (map.isNotEmpty()) {
267- Singular .eventJSON(" UserAttribute" , (map as Map <* , * >? )?.let { JSONObject (it) })
316+ executeIfSingularInitialized(
317+ {
318+ Singular .eventJSON(" UserAttribute" , (map as Map <* , * >? )?.let { JSONObject (it) })
319+ }, forceInitSingular = false , " setUserAttribute"
320+ )
268321 }
269322 }
270323
@@ -312,34 +365,44 @@ open class SingularKit : KitIntegration(), ActivityListener, EventListener,
312365 filteredMParticleUser : FilteredMParticleUser
313366 ) {
314367
315- consentState.ccpaConsentState?.let { Singular .limitDataSharing(it.isConsented) }
368+ executeIfSingularInitialized({
369+ consentState.ccpaConsentState?.let { Singular .limitDataSharing(it.isConsented) }
370+ }, forceInitSingular = false , " onConsentStateUpdated" )
316371
317372 }
318373
319374 override fun setAllUserAttributes (map : Map <String , String >, map1 : Map <String , List <String >>) {}
320375 override fun removeUserAttribute (s : String ) {}
321376 override fun setUserIdentity (identityType : IdentityType , s : String ) {
322377 if (identityType == IdentityType .CustomerId ) {
323- Singular .setCustomUserId(s)
378+ executeIfSingularInitialized({
379+ Singular .setCustomUserId(s)
380+ }, forceInitSingular = false , " setUserIdentity" )
324381 }
325382 }
326383
327384 override fun removeUserIdentity (identityType : IdentityType ) {
328385 if (identityType == IdentityType .CustomerId ) {
329- Singular .unsetCustomUserId()
386+ executeIfSingularInitialized({
387+ Singular .unsetCustomUserId()
388+ isInitialized = false
389+ }, forceInitSingular = false , " removeUserIdentity" )
330390 }
331391 }
332392
333393 override fun logout (): List <ReportingMessage > {
334- Singular .unsetCustomUserId()
335394 val messageList: MutableList <ReportingMessage > = ArrayList ()
336- messageList.add(ReportingMessage .logoutMessage(this ))
395+ executeIfSingularInitialized({
396+ Singular .unsetCustomUserId()
397+ isInitialized = false
398+ messageList.add(ReportingMessage .logoutMessage(this ))
399+ }, forceInitSingular = false , " logout" )
337400 return messageList
338401 }
339402
340403 override fun onApplicationForeground () {
341404 // Handling deeplinks when the application resumes from background
342- Singular . init (context, buildSingularConfig(singularSettings) )
405+ initializeSingular( )
343406 }
344407
345408 override fun onApplicationBackground () {} // endregion
0 commit comments