Closed rostopira closed 6 years ago
@rostopira Thanks for the details. Could you share which OneSignal SDK methods you are calling? Are your calls to OneSignal on the main thread? Or are some on a background thread? We haven't seen other reports of this crash so it might be an race condition with this.
Here is code, that is used in my app
At the Application onCreate:
OneSignal.setLocationShared(false)
OneSignal
.startInit(this)
.setNotificationOpenedHandler {
if (it.notification.payload.collapseId?.contains("chat") == true)
startActivity(newIntent<ChatActivity>(Intent.FLAG_ACTIVITY_NEW_TASK))
else {
if (!it.notification.payload.launchURL.isNullOrBlank()) {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(it.notification.payload.launchURL))
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(intent)
} else
startActivity(newIntent<SplashScreen>(Intent.FLAG_ACTIVITY_NEW_TASK))
}
}
.init()
OneSignal.setInFocusDisplaying(OneSignal.OSInFocusDisplayOption.None)
OneSignal.idsAvailable { osId, _ ->
val kgl = this@initOneSignal
kgl.user.pushId = osId
with(kgl.defaultSharedPreferences) {
if (getString("oneSignalId", null) != osId) {
edit().putString("oneSignalId", osId).apply()
Command(ID_UPDATE, osId).send()
}
}
}
NotificationExtenderService:
class PushProcessor: NotificationExtenderService() {
override fun onNotificationProcessing(notification: OSNotificationReceivedResult): Boolean {
val cp = notification.payload?.collapseId
if (cp?.contains("promo") == true) {
val sp = defaultSharedPreferences
if (sp.getBoolean(cp, false))
return true
sp.set(cp to true)
return UserData.appHidden
}
val addData = notification.payload?.additionalData ?: return UserData.appHidden
return (notification.payload?.collapseId?.contains("chat") == true && ChatActivity.opened)
|| processPush(addData, this) || UserData.appHidden
}
}
private fun processPush(data: JSONObject, ctx: Service): Boolean {
try {
val id = data.getString("id") ?: return false
val type = data.getInt("t")
val value = data.getString("v") ?: ""
if (type == Pushable.MESSAGE && ChatActivity.opened) return true
if (id != "web" && !ctx.kgl.family.contains(id))
ctx.kgl.refresh()
if (type<10) {
val n = PushNotification(id, type, value)
if (data.has("ts")) {
n.ts = data.getLong("ts")
if (n.ts != 0L && timestamp()-n.ts > DateUtils.HOUR_IN_MILLIS * 2)
return true
if (type == Pushable.SAFE || type == Pushable.DANGER) {
val sps = ctx.getSharedPreferences("spsts", Context.MODE_PRIVATE)
if (sps.getLong(id, 0L) > n.ts)
return true
sps.edit().putLong(id, n.ts).apply()
}
}
n.show(ctx)
} else {
if (BuildConfig.DEBUG) {
Log.e("OS", "Received command: $type")
}
Command(id, type, value).exec(ctx)
}
return true
} catch (parseException: JSONException) {
parseException.fly()
return false
} catch (unitialized: UninitializedPropertyAccessException) {
return false
}
}
Other internal usage (used on background thread and main thread as well):
package com.kid.gl.backend
import android.util.Log
import com.google.firebase.database.*
import com.kid.gl.FSU_TAG
import com.kid.gl.utils.*
import com.mcxiaoke.koi.ext.timestamp
import com.onesignal.OneSignal
import org.json.JSONObject
import java.util.*
import kotlin.concurrent.schedule
abstract class Pushable {
companion object {
const val PARENTS = "par"
const val KIDS = "kids"
const val MAX_TTL = 86400
const val SAFE = 1
const val DANGER = -1
const val GPS_DISABLED = -3
const val MESSAGE = 0
const val BATTERY_LOW = -4
const val SHUTDOWN = -5
private val dbRef get() = DBMan.getDb().child("enlv").child(tryGetKGL()!!.famkey)
}
abstract val value: String
abstract val type: Int
@get:Exclude protected val kgl by lazy { tryGetKGL() }
@get:Exclude private var retries = 0
open fun send(to: String? = null, callback: ((Boolean)->Unit)? = null) {
if (kgl==null) {
FirePig.fly("Pushable: Failed to get app context")
return
}
if (kgl!!.state<0) {
Log.wtf(FSU_TAG, "Id or famkey is null")
return
}
val withWeb = type < 10 //&& type != 0
val ids = when(to) {
null -> Ids[A, withWeb]
PARENTS -> Ids[P, withWeb]
KIDS -> Ids[K, withWeb]
else -> Ids[to]
}
if (ids=="") {
if (kgl!!.family.size>0) {
Ids.refresh(kgl!!.family)
defer(to)
}
return
}
OneSignal.postNotification(json(ids), object : OneSignal.PostNotificationResponseHandler{
override fun onSuccess(response: JSONObject?) {
callback?.invoke(true)
}
override fun onFailure(response: JSONObject) {
callback?.invoke(false)
Log.wtf("Push delivery error", response.toString())
Requirements.INTERNET.check(kgl!!)
try {
val err = response.getJSONObject("errors")
if (err.has("invalid_player_ids")) {
val invalidIds = err.getJSONArray("invalid_player_ids")
for (i in 0 until invalidIds.length())
Ids.resend(invalidIds.getString(i), this@Pushable)
}
} catch (e: Exception) {
val str = response.toString()
if (str.toLowerCase(Locale.US).contains("unknown"))
defer(to)
else {
FirePig.fly(response.toString())
e.fly("Pushable")
}
}
}
})
if (retries == 0 && (type == SAFE || type == DANGER)) {
dbRef.push().setValue(mapOf(
"id" to kgl!!.userId,
"message" to "${if (type==SAFE) "entered" else "outof"}://$value",
"timestamp" to timestamp()
))
}
}
open fun defer(to: String?): Boolean {
return if (retries++<4) {
Timer().schedule(1000L) { send(to) }
true
} else false
}
protected abstract fun json(ids: String): JSONObject
protected open val ttl get() = 3600
}
Another one (on both threads as well):
fun Context.setUserProperty(name: String, value: Any) {
anal.setUserProperty(name, value.toString())
OneSignal.sendTag(name, value.toString())
}
Is there any progress on this?
The issue was fixed in the PR above and is now released in version 3.9.1
i have tested version 3.9.1 and 3.9.3 both causes the same issue.
Fatal Exception: java.lang.NullPointerException
at com.onesignal.OneSignalPrefs$WritePrefHandlerThread.flushBufferToDisk(OneSignalPrefs.java:121)
at com.onesignal.OneSignalPrefs$WritePrefHandlerThread.access$000(OneSignalPrefs.java:84)
at com.onesignal.OneSignalPrefs$WritePrefHandlerThread$1.run(OneSignalPrefs.java:112)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:146)
at android.os.HandlerThread.run(HandlerThread.java:61)
This is still not resolved. Running into this with 3.9.1 as well.
More than 3k of my users are currently affected by this issue (stats for 48 hours) on 3.9.1 as well (Total: more than 6.2k crashes for 48 hours)
@rostopira apologies about the crashes your users are experiencing. We’ve identified the cause of the problem and will be releasing an update to fix it shortly. It’s very similar to the issue we fixed in 3.9.1. We’ll be checking the SDK thoroughly to make sure there aren’t further NPE’s like this.
@Nightsd01 any progress on this? This already caused delay in our release cycle
@rostopira Sorry for the delay on this, we believe we have identified the root issue now. We should have a fix next week. We will update this ticket with our progress
@jkasten2 more than week passed already. I'm starting to loose hope. If you don't have any ETA, than I'll rollback to the old version
@rostopira Sorry for the delay. We just released 3.9.2 which includes a fix for this issue.
I can confirm this issues is fixed Great job
Description: 20% of devices on new release experience critical issue Reports error log:
Environment
Steps to Reproduce Issue: Unknown