Описание:
Мы получаем несколько отчетов о сбоях из RNOneSignal.getDeviceState
, трассировка стека прилагается ниже.
Это влияет на каждую версию Android SDK и производителя.
Среда
"react-native-onesignal": "^4.0.2",
react: 17.0.1 => 17.0.1
react-native: 0.64.0-rc.2 => 0.64.0-rc.2
Шаги по воспроизведению проблемы:
Не удалось воспроизвести проблему, о ней сообщается в панели управления сбоями Google Play.
Что-нибудь еще:
at com.geektime.rnonesignalandroid.RNOneSignal.getDeviceState (RNOneSignal.java:4)
at java.lang.reflect.Method.invoke (Method.java)
at com.facebook.react.bridge.JavaMethodWrapper.invoke (JavaMethodWrapper.java:147)
at com.facebook.react.bridge.JavaModuleWrapper.invoke (JavaModuleWrapper.java:21)
at com.facebook.react.bridge.queue.NativeRunnable.run (NativeRunnable.java)
at android.os.Handler.handleCallback (Handler.java:883)
at android.os.Handler.dispatchMessage (Handler.java:100)
at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage (MessageQueueThreadHandler.java)
at android.os.Looper.loop (Looper.java:237)
at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run (MessageQueueThreadImpl.java:37)
at java.lang.Thread.run (Thread.java:919)
+1.
java.lang.NullPointerException:
at com.geektime.rnonesignalandroid.RNOneSignal.getDeviceState (RNOneSignal.java:4)
at java.lang.reflect.Method.invoke (Method.java)
at com.facebook.react.bridge.JavaMethodWrapper.invoke (JavaMethodWrapper.java:147)
at com.facebook.react.bridge.JavaModuleWrapper.invoke (JavaModuleWrapper.java:21)
at com.facebook.react.bridge.queue.NativeRunnable.run (NativeRunnable.java)
at android.os.Handler.handleCallback (Handler.java:873)
at android.os.Handler.dispatchMessage (Handler.java:99)
at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage (MessageQueueThreadHandler.java)
at android.os.Looper.loop (Looper.java:224)
at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run (MessageQueueThreadImpl.java:37)
at java.lang.Thread.run (Thread.java:764)
Привет, Диего,
Спасибо, что сообщили об этой проблеме.
Не могли бы вы включить код, который вы используете? Также не могли бы вы предоставить информацию о среде (например: производитель и модель устройства, ОС и т. Д.)?
Ваше здоровье
Привет, Диего,
Спасибо, что сообщили об этой проблеме.Не могли бы вы включить код, который вы используете? Также не могли бы вы предоставить информацию о среде (например: производитель и модель устройства, ОС и т. Д.)?
Ваше здоровье
Спасибо за ответ.
Об этом сообщается на нашей консоли Google Play со скоростью около 50 сбоев в неделю, у меня нет никакого способа воспроизвести это.
То же самое.
info Получение информации о системе и библиотеках ...
Система:
ОС: macOS 10.15.7
Процессор: (4) x64 Intel (R) Core (TM) i5-5257U CPU @ 2,70 ГГц
Память: 36,86 МБ / 8,00 ГБ
Оболочка: 5.7.1 - / bin / zsh
Двоичные файлы:
Узел: 10.22.0 - ~ / .nvm / versions / node / v10.22.0 / bin / node
Пряжа: 1.22.4 - / usr / local / bin / yarn
npm: 6.14.6 - ~ / .nvm / версии / узел / v10.22.0 / bin / npm
Сторож: 4.9.0 - / usr / local / bin / watchman
Менеджеры:
CocoaPods: 1.10.0 - / usr / local / bin / pod
SDK:
SDK для iOS:
Платформы: iOS 13.6, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2.
Android SDK:
Уровни API: 23, 25, 26, 28, 29
Инструменты сборки: 28.0.3, 29.0.2, 29.0.3
Android NDK: не найдено
Иды:
Android-студия: 3.6 AI-192.7142.36.36.6308749
Xcode: 11.6 / 11E708 - / usr / bin / xcodebuild
Языки:
Java: 1.8.0_242 - / usr / bin / javac
Python: 2.7.16 - / usr / bin / python
npmPackages:
@ response-native-community / cli: не найдено
реагировать: 16.13.1 => 16.13.1
реагировать-родной: 0.63.3 => 0.63.3
react-native-macos: не найдено
npmGlobalPackages:
реагировать-родной : не найдено
"react-native": "0.63.3",
"реагировать-родной-одинсигнал": "^ 4.0.1",
Неустранимое исключение: java.lang.NullPointerException
Попытка вызвать виртуальный метод org.json.JSONObject com.onesignal.OSDeviceState.toJSONObject () для ссылки на нулевой объект
com.geektime.rnonesignalandroid.RNOneSignal.getDeviceState (RNOneSignal.java:239)
java.lang.reflect.Method.invoke (Method.java)
com.facebook.react.bridge.JavaMethodWrapper.invoke (JavaMethodWrapper.java:372)
com.facebook.react.bridge.JavaModuleWrapper.invoke (JavaModuleWrapper.java:151)
com.facebook.react.bridge.queue.NativeRunnable.run (NativeRunnable.java)
android.os.Handler.handleCallback (Handler.java:883)
android.os.Handler.dispatchMessage (Handler.java:100)
com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage (MessageQueueThreadHandler.java:27)
android.os.Looper.loop (Looper.java:241)
com.facebook.react.bridge.queue.MessageQueueThreadImpl $ 4.run (MessageQueueThreadImpl.java:226)
java.lang.Thread.run (Thread.java:919)
Предоставьте фрагмент кода для облегчения воспроизведения.
Ваше здоровье
@rgomezp
Ошибка возникает при вызове OneSignal.getDeviceState ():
const getDeviceState = async () => {
const deviceState = await OneSignal.getDeviceState();
console.log({ deviceState });
}
Исключение составляют:
Fatal Exception: java.lang.NullPointerException
Attempt to invoke virtual method 'org.json.JSONObject com.onesignal.OSDeviceState.toJSONObject()' on a null object reference
com.geektime.rnonesignalandroid.RNOneSignal.getDeviceState (RNOneSignal.java:239)
java.lang.reflect.Method.invoke (Method.java)
com.facebook.react.bridge.JavaMethodWrapper.invoke (JavaMethodWrapper.java:372)
com.facebook.react.bridge.JavaModuleWrapper.invoke (JavaModuleWrapper.java:151)
com.facebook.react.bridge.queue.NativeRunnable.run (NativeRunnable.java)
android.os.Handler.handleCallback (Handler.java:883)
android.os.Handler.dispatchMessage (Handler.java:100)
com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage (MessageQueueThreadHandler.java:27)
android.os.Looper.loop (Looper.java:241)
com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run (MessageQueueThreadImpl.java:226)
java.lang.Thread.run (Thread.java:919)
Пакеты OneSignal и React Native:
"react-native": "0.63.3",
"react-native-onesignal": "^4.0.1",
````
The react native info:
```typescript
info Fetching system and libraries information...
System:
OS: macOS 10.15.7
CPU: (4) x64 Intel(R) Core(TM) i5-5257U CPU @ 2.70GHz
Memory: 36.86 MB / 8.00 GB
Shell: 5.7.1 - /bin/zsh
Binaries:
Node: 10.22.0 - ~/.nvm/versions/node/v10.22.0/bin/node
Yarn: 1.22.4 - /usr/local/bin/yarn
npm: 6.14.6 - ~/.nvm/versions/node/v10.22.0/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
Managers:
CocoaPods: 1.10.0 - /usr/local/bin/pod
SDKs:
iOS SDK:
Platforms: iOS 13.6, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2
Android SDK:
API Levels: 23, 25, 26, 28, 29
Build Tools: 28.0.3, 29.0.2, 29.0.3
Android NDK: Not Found
IDEs:
Android Studio: 3.6 AI-192.7142.36.36.6308749
Xcode: 11.6/11E708 - /usr/bin/xcodebuild
Languages:
Java: 1.8.0_242 - /usr/bin/javac
Python: 2.7.16 - /usr/bin/python
npmPackages:
@react-native-community/cli: Not Found
react: 16.13.1 => 16.13.1
react-native: 0.63.3 => 0.63.3
react-native-macos: Not Found
npmGlobalPackages:
react-native: Not Found
Возникает такая же проблема.
"react-native": "^ 0.63.4",
"реагировать-родной-одинсигнал": "^ 4.0.3"
Я обновил "react-native-onesignal": "^ 3.9.3" до "react-native-onesignal": "^ 4.0.3". У меня сейчас вылеты. Я обновил код инициализации, как указано выше. Я добавил свежее.
...
пусть устройство = ожидание OneSignal.getDeviceState ();
...
Из журнала сбоев Play Store
java.lang.NullPointerException:
в com.geektime.rnonesignalandroid.RNOneSignal.getDeviceState (RNOneSignal.java)
в java.lang.reflect.Method.invoke (Method.java)
в com.facebook.react.bridge.JavaMethodWrapper.invoke (JavaMethodWrapper.java)
в com.facebook.react.bridge.JavaModuleWrapper.invoke (JavaModuleWrapper.java)
в com.facebook.react.bridge.queue.NativeRunnable.run (NativeRunnable.java)
в android.os.Handler.handleCallback (Handler.java:739)
в android.os.Handler.dispatchMessage (Handler.java:95)
в com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage (MessageQueueThreadHandler.java)
в android.os.Looper.loop (Looper.java:148)
в com.facebook.react.bridge.queue.MessageQueueThreadImpl $ 4.run (MessageQueueThreadImpl.java)
в java.lang.Thread.run (Thread.java:818)
Журнал сбоев Firebase
Неустранимое исключение: java.lang.NullPointerException: попытка вызвать виртуальный метод org.json.JSONObject com.onesignal.g0.a () для ссылки на нулевой объект
в com.geektime.rnonesignalandroid.RNOneSignal.getDeviceState (RNOneSignal.java:4)
в java.lang.reflect.Method.invoke (Method.java)
Привет,
Спасибо за информацию, но если бы кто-нибудь мог предоставить пример кода, это было бы наиболее полезно. Этот
const getDeviceState = async () => {
const deviceState = ждать OneSignal.getDeviceState ();
console.log ({deviceState});
}
не предоставляет достаточно информации для воспроизведения. Что нам нужно, так это дополнительный контекст относительно того, как и где это используется.
Например: как вызов getDeviceState
связан с инициализацией OneSignal? или в какой функции жизненного цикла RN это вызывается?
Убедитесь, что предоставлен весь контекст, необходимый для решения этой проблемы, поскольку предоставленные трассировки стека не совсем обеспечивают то, что нам нужно.
Я подозреваю, что это могло произойти, если getDeviceState
вызывается слишком быстро. Можете ли вы попробовать переместить getDeviceState
в точку вашего кода, которая гарантированно запустится после завершения инициализации OneSignal? например: поместите его в обратный вызов наблюдателю изменения подписки.
Помните, что getDeviceState
делает снимок во время его вызова. По этой причине не кешируйте состояние, а, скорее, повторно получите его по мере необходимости.
@rgomezp
Привет, в App.tsx, нашей точке входа, у нас есть:
const oneSignalIntialize = async () => {
OneSignal.setAppId('xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx');
}
const App = () => {
useEffect(() => {
oneSignalIntialize();
}, []);
return (
<LoginFlow />
);
}
После входа в систему, если это удалось, появится экран приветствия:
const getDeviceState = async () => {
const deviceState = await OneSignal.getDeviceState();
console.log({ deviceState });
}
const WelcomeScreen = () => {
useEffect(() => {
getDeviceState();
}, []);
return (
<Components />
);
}
Привет @renatobentorocha!
Спасибо, что поделились с нами кодом!
Хук useEffect здесь может быть вызван для инициализации SDK в основном компоненте приложения. По сути, это асинхронный вызов, который вызывается, как только компонент монтируется, но нет состояния, которое проверяет, была ли завершена инициализация.
Взаимодействие с другими людьми
Вы можете использовать ловушку useState, чтобы добавить состояние для проверки статуса инициализации перед рендерингом экрана приветствия.
Взаимодействие с другими людьми
Другая рекомендация, предложенная @rgomezp , - запустить его в обратном вызове addSubscriptionObserver (извините за то, что я слишком быстро говорил об устаревшем getPermissionSubscriptionState ранее), что гарантирует, что SDK был успешно инициализирован до доступа к состоянию устройства.
Взаимодействие с другими людьми
Сообщите нам, поможет ли это решить проблему,
Взаимодействие с другими людьми
Спасибо
Взаимодействие с другими людьми
Привет @ tyang1 Спасибо за внимание, но в документации с одним сигналом для этого обратного вызова (getPermissionSubscriptionState) говорится:
Я протестирую с addSubscriptionObserver
и дам вам знать, что происходит
Получение этого тоже. Не умею воспроизводить. @rgomezp, возможно, это проблема с
Привет,
Я не думаю, что это проблема с потоками, поскольку трассировки стека указывают на то, что это, скорее, происходит на уровне оболочки. Это определенно могло быть ошибкой. Нам просто нужны надежные шаги воспроизведения, чтобы двигаться вперед с разрешением.
Интересно, @renatobentorocha, что вы сообщили, что 98% это происходит в фоновом режиме.
@oferRounds @dijinshopwise вы тоже это видите?
+1
@rgomezp следуйте коду:
async componentDidMount() {
this._isMounted = true
/* O N E S I G N A L S E T U P */
OneSignal.setAppId('***********************************')
OneSignal.setLogLevel(0, 0)
OneSignal.setRequiresUserPrivacyConsent(false)
/* O N E S I G N A L H A N D L E R S */
OneSignal.setNotificationWillShowInForegroundHandler(notifReceivedEvent => {
let notification = notifReceivedEvent.getNotification()
const buttonOk = {
text: 'OK', onPress: () => {
notifReceivedEvent.complete()
},
}
Alert.alert(notification.title, notification.body, [buttonOk])
if (notification.additionalData) {
//
}
})
OneSignal.setNotificationOpenedHandler(notification => {
//
})
OneSignal.disablePush(true)
const deviceState = await OneSignal.getDeviceState()
if (Platform.OS === 'ios' && !deviceState.isSubscribed) {
OneSignal.promptForPushNotificationsWithUserResponse(function(accepted) {
//
});
}
// ...
}
Я перехожу на старую версию, и Google Play предупреждает об этой же ошибке.
com.geektime.rnonesignalandroid.RNOneSignal.getDeviceState
Любое предложение? Какое-нибудь временное решение?
Мы до сих пор получаем сотни таких сбоев, есть новости?
@ diego-paired нашим временным обходным решением было отложить вызов getDeviceState()
после инициализации OneSingal (мы добавили 2-секундную задержку)
@ diego-paired нашим временным обходным решением было отложить вызов
getDeviceState()
после инициализации OneSingal (мы добавили 2-секундную задержку)
Спасибо за чаевые
Привет @renatobentorocha!
Спасибо, что поделились с нами кодом!
Хук useEffect здесь может быть вызван для инициализации SDK в основном компоненте приложения. По сути, это асинхронный вызов, который вызывается, как только компонент монтируется, но нет состояния, которое проверяет, была ли завершена инициализация.
Взаимодействие с другими людьми
Вы можете использовать ловушку useState, чтобы добавить состояние для проверки статуса инициализации перед рендерингом экрана приветствия.
Взаимодействие с другими людьми
Другая рекомендация, предложенная @rgomezp , - запустить его в обратном вызове addSubscriptionObserver (извините за то, что я слишком быстро говорил об устаревшем getPermissionSubscriptionState ранее), что гарантирует, что SDK был успешно инициализирован до доступа к состоянию устройства.
Взаимодействие с другими людьми
Сообщите нам, поможет ли это решить проблему,
Взаимодействие с другими людьми
Спасибо
@ diego-paired @ дан-разработчик
Я последовал предложению @rgomezp, и сбои на данный момент прекратились.
OneSignal.addSubscriptionObserver(() => {
OneSignal.getDeviceState().then((deviceState) => {
console.log({deviceState})
});
});
Используя тестовое приложение , добавили этот код к кнопке:
Ситуация 1
let getDeviceStateButton = this.renderButtonView(
"Get Device State",
isExternalUserIdLoading || isPrivacyConsentLoading,
() => {
console.log("Attempting to get device state");
this.setState({ isExternalUserIdLoading: true }, () => {
// OneSignal getDeviceState
let deviceState = OneSignal.getDeviceState();
console.log("deviceState: ", deviceState);
console.log("deviceState.isSubscribed: ", deviceState.isSubscribed);
this.setState({ isExternalUserIdLoading: false, isSubscribed: deviceState.isSubscribed });
console.log("this.state.isSubscribed after calling setState: ", this.state.isSubscribed);
console.log("deviceState.userId: ", deviceState.userId)
});
});
Журнал показывает:
2021-03-25 20:06:14.589544-0700 jonexample[751:27269] [javascript] Attempting to get device state
2021-03-25 20:06:14.645290-0700 jonexample[751:27269] [javascript] 'deviceState: ', { _U: 0, _V: 0, _W: null, _X: null }
2021-03-25 20:06:14.647385-0700 jonexample[751:27269] [javascript] 'deviceState.isSubscribed: ', undefined
2021-03-25 20:06:14.647768-0700 jonexample[751:27269] [javascript] 'this.state.isSubscribed after calling setState: ', undefined
2021-03-25 20:06:14.647897-0700 jonexample[751:27269] [javascript] 'deviceState.userId: ', undefined
Однако при использовании примера кода, предоставленного в componentDidMount :
Ситуация 2
async componentDidMount(){
const deviceState = await OneSignal.getDeviceState();
this.setState({ isSubscribed : deviceState.isSubscribed});
console.log("componentDidMount deviceState: ", deviceState);
console.log("componentDidMount deviceState.isSubscribed: ", deviceState.isSubscribed);
console.log("componentDidMount deviceState.userId: ", deviceState.userId);
}
Журнал показывает:
2021-03-25 20:14:46.521099-0700 jonexample[1326:55465] [javascript] 'componentDidMount deviceState: ', { userId: '92aa2978-3f53-454e-b1a6-652c43f0dba4',
2021-03-25 20:14:46.521328-0700 jonexample[1326:55465] [javascript] 'componentDidMount deviceState.isSubscribed: ', true
2021-03-25 20:14:46.521435-0700 jonexample[1326:55465] [javascript] 'componentDidMount deviceState.userId: ', '92aa2978-3f53-454e-b1a6-652c43f0dba4'
@rgomezp - это ожидаемое поведение сценария 1?
@ diego-paired @renatobentorocha @ dan-developer не могли бы вы поделиться своими примерами или подтвердить, что вы видите обе вышеуказанные ситуации?
Пожалуйста, подробно опишите, как вы используете этот метод, и укажите шаги, которые необходимо воспроизвести.
@ jfishman1 Посмотрите документацию . Вы увидите, что getDeviceState
- это асинхронная функция, поэтому не забудьте дождаться ее или использовать then
.
Тем не менее, похоже, есть хорошая возможность справиться с этим в SDK, чтобы избежать этих сбоев. Спасибо, что поднялись на поверхность. Мы рассмотрим, какие изменения можно внести, чтобы с ними легче справляться.
Если углубиться в это немного дальше, кажется, что наиболее вероятной причиной этого является то, что нативная сторона пытается получить состояние устройства до загрузки контекста.
if (appContext == null) {
logger.error("OneSignal.initWithContext has not been called. Could not get OSDeviceState");
return null;
}
Для подтверждения найдите OneSignal.initWithContext has not been called. Could not get OSDeviceState
в своем собственном logcat (например, откройте Android Studio).
А пока, похоже, мы можем добавить проверку в мост Android, чтобы предотвратить полный сбой.
В любом случае, обратите внимание:
Мы по-прежнему рекомендуем получать данные о состоянии устройства только через обозреватель изменений подписки, чтобы убедиться, что вы не получаете сведения о состоянии устройства слишком рано.
Спасибо за ваше терпение.
От № 1085:
Вместо того, чтобы задерживать получение состояния устройства с помощью таймера, попробуйте поместить вызов функции getDeviceState
в обозреватель подписки. Таким образом, вы будете знать, что на него подписаны. например:
OneSignal.addSubscriptionObserver(async (event) => {
this.OSLog("OneSignal: subscription changed:", event);
if (event.to.isSubscribed) {
const state = await OneSignal.getDeviceState();
// do something with the device state
}
});
Обновление: теперь это исправлено в последней версии 4.0.7.
Я обновился до последней репо 4.0.7. Я не уверен, что спрашиваю в нужном месте, но на некоторых симуляторах iOS и устройствах Android я даже получаю эти поля только с deviceState, например, как это. Нет даже поля userId.
{"rootTag":21,"initialProps":{}}
WARN {"hasNotificationPermission": false, "isEmailSubscribed": false, "isPushDisabled": false, "isSMSSubscribed": false, "isSubscribed": false, "notificationPermissionStatus": 0}
Самый полезный комментарий
Спасибо за чаевые