React-native-onesignal: [CRASH][ANDROID] NullPointerException di getDeviceState

Dibuat pada 6 Feb 2021  ·  28Komentar  ·  Sumber: OneSignal/react-native-onesignal

Deskripsi:
Kami menerima sejumlah laporan kerusakan yang berasal dari RNOneSignal.getDeviceState , jejak tumpukan terlampir di bawah.

Ini memengaruhi setiap versi dan pabrikan SDK Android.

Lingkungan Hidup
"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

Langkah-langkah untuk Mereproduksi Masalah:
Belum dapat mereproduksi masalah, dilaporkan di dasbor kerusakan Google Play.

Ada yang lain:

  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)
Android Possible Bug

Komentar yang paling membantu

@diego-paired solusi sementara kami adalah menunda panggilan ke getDeviceState() setelah OneSingal init (kami menambahkan penundaan 2 detik)

terima kasih atas tipnya

Semua 28 komentar

+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)

Halo Diego,
Terima kasih telah melaporkan permasalahan ini.

Bisakah Anda memasukkan kode yang Anda gunakan? Anda juga dapat memberikan info lingkungan (misalnya: merek dan model perangkat, OS, dll...)?

Bersulang

Halo Diego,
Terima kasih telah melaporkan permasalahan ini.

Bisakah Anda memasukkan kode yang Anda gunakan? Anda juga dapat memberikan info lingkungan (misalnya: merek dan model perangkat, OS, dll...)?

Bersulang

Terima kasih untuk balasan Anda.

Ini dilaporkan di konsol Google Play kami dengan kecepatan sekitar 50 crash per minggu, saya tidak punya cara untuk mereproduksinya.

image

Sama disini.

info Mengambil informasi sistem dan perpustakaan...
Sistem:
OS: macOS 10.15.7
CPU: (4) x64 Intel(R) Core(TM) i5-5257U CPU @ 2.70GHz
Memori: 36,86 MB / 8,00 GB
Kulit: 5.7.1 - /bin/zsh
Biner:
Node: 10.22.0 - ~/.nvm/versions/node/v10.22.0/bin/node
Benang: 1.22.4 - /usr/local/bin/benang
npm: 6.14.6 - ~/.nvm/versions/node/v10.22.0/bin/npm
Penjaga: 4.9.0 - /usr/local/bin/watchman
Manajer:
CocoaPods: 1.10.0 - /usr/local/bin/pod
SDK:
SDK iOS:
Platform: iOS 13.6, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2
SDK Android:
Level API: 23, 25, 26, 28, 29
Alat Bangun: 28.0.3, 29.0.2, 29.0.3
Android NDK: Tidak Ditemukan
IDE:
Android Studio: 3.6 AI-192.7142.36.36.6308749
Xcode: 11.6/11E708 - /usr/bin/xcodebuild
Bahasa:
Java: 1.8.0_242 - /usr/bin/javac
Python: 2.7.16 - /usr/bin/python
npmPaket:
@react-native-community/cli: Tidak Ditemukan
bereaksi: 16.13.1 => 16.13.1
reaksi asli: 0.63.3 => 0.63.3
react-native-macos: Tidak Ditemukan
npmGlobalPaket:
reaksi-asli : Tidak Ditemukan

"react-asli": "0.63.3",
"react-native-onesignal": "^4.0.1",

Pengecualian Fatal: java.lang.NullPointerException
Mencoba memanggil metode virtual 'org.json.JSONObject com.onesignal.OSDeviceState.toJSONObject()' pada referensi objek nol

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)

Harap berikan cuplikan kode untuk memfasilitasi reproduksi.

Bersulang

@rgomezp

Kesalahan terjadi dalam panggilan OneSignal.getDeviceState():

const getDeviceState =  async () => {
     const deviceState = await OneSignal.getDeviceState();
     console.log({ deviceState });
}

Pengecualiannya adalah:

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)

Paket OneSignal dan React Native adalah:

"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

Mendapatkan masalah yang sama.

"react-asli": "^0.63.4",
"react-native-onesignal": "^4.0.3"

Saya memutakhirkan dari "react-native-onesignal": "^3.9.3" menjadi "react-native-onesignal": "^4.0.3". Saya mendapatkan crash sekarang. Saya telah memperbarui kode init sama seperti di atas. Saya menambahkan dengan segar.

...
let device = menunggu OneSignal.getDeviceState();
...

Dari Log Kerusakan Play Store

java.lang.NullPointerException:
di com.geektime.rnonesignalandroid.RNOneSignal.getDeviceState (RNOneSignal.java)
di java.lang.reflect.Method.invoke (Method.java)
di com.facebook.react.bridge.JavaMethodWrapper.invoke (JavaMethodWrapper.java)
di com.facebook.react.bridge.JavaModuleWrapper.invoke (JavaModuleWrapper.java)
di com.facebook.react.bridge.queue.NativeRunnable.run (NativeRunnable.java)
di android.os.Handler.handleCallback (Handler.java:739)
di android.os.Handler.dispatchMessage (Handler.java:95)
di com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage (MessageQueueThreadHandler.java)
di android.os.Looper.loop (Looper.java: 148)
di com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run (MessageQueueThreadImpl.java)
di java.lang.Thread.run (Thread.java:818)

Log Kerusakan Firebase

Pengecualian Fatal: java.lang.NullPointerException: Mencoba memanggil metode virtual 'org.json.JSONObject com.onesignal.g0.a()' pada referensi objek nol
di com.geektime.rnonesignalandroid.RNOneSignal.getDeviceState(RNOneSignal.java:4)
di java.lang.reflect.Method.invoke(Method.java)

apa kabar,
Terima kasih atas informasinya, tetapi jika seseorang dapat memberikan contoh kode, itu akan sangat membantu. Ini

const getDeviceState = async () => {
const deviceState = menunggu OneSignal.getDeviceState();
console.log({ deviceState });
}

tidak cukup memberikan informasi yang cukup untuk direproduksi. Apa yang kita butuhkan adalah beberapa konteks tentang bagaimana dan di mana ini digunakan.

Misalnya: bagaimana hubungan panggilan ke getDeviceState dengan inisialisasi OneSignal? atau apa fungsi siklus hidup RN yang dipanggil?

Harap pastikan untuk memberikan semua konteks yang diperlukan untuk menyelesaikan ini karena pelacakan tumpukan yang disediakan tidak cukup memberikan apa yang kami butuhkan.

Saya menduga ini mungkin terjadi jika getDeviceState dipanggil terlalu cepat. Bisakah Anda mencoba memindahkan getDeviceState ke titik dalam kode Anda yang dijamin berjalan setelah inisialisasi OneSignal selesai? misalnya: masukkan ke dalam panggilan balik ke pengamat perubahan langganan.

Ingat bahwa getDeviceState menangkap snapshot pada saat dipanggil. Untuk alasan itu, jangan men-cache status, tetapi dapatkan kembali sesuai kebutuhan.

Referensi

@rgomezp

Hai, di App.tsx, titik masuk kami, kami memiliki:

const oneSignalIntialize = async () => {
  OneSignal.setAppId('xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx');
}

const App = () => {
  useEffect(() => {
    oneSignalIntialize();

  }, []);

return (
    <LoginFlow />
);

}

Setelah alur masuk, jika ini berhasil, kami memiliki layar selamat datang:

const getDeviceState = async () => {
    const deviceState = await OneSignal.getDeviceState(); 
    console.log({ deviceState });
}

const WelcomeScreen = () => {
  useEffect(() => {
    getDeviceState();

  }, []);

return (
    <Components />
);

}

Screen Shot 2021-02-18 at 10 59 35

Hai @renatobentorocha ,
Terima kasih telah berbagi kode dengan kami!
Kait useEffect di sini dapat dipanggil untuk menginisialisasi SDK dalam komponen Aplikasi utama. Ini pada dasarnya adalah panggilan async yang dipanggil segera setelah komponen dipasang, tetapi tidak ada status yang memeriksa apakah inisialisasi telah selesai.
</s> </s> </s> </s> </s>
Anda dapat menggunakan kait useState untuk menambahkan status guna memeriksa status init sebelum menampilkan layar Selamat Datang.
</s> </s> </s> </s> </s>
Rekomendasi lain, seperti yang disarankan oleh @rgomezp , adalah menjalankannya dalam panggilan balik ke addSubscriptionObserver (maaf karena saya berbicara terlalu cepat pada getPermissionSubscriptionState yang sudah tidak digunakan sebelumnya), yang akan menjamin bahwa SDK telah berhasil diinisialisasi sebelum mengakses status perangkat.
</s> </s> </s> </s> </s>
Beri tahu kami jika ini membantu menyelesaikan masalah,
</s> </s> </s> </s> </s>
Terima kasih
</s> </s> </s> </s> </s>

Hai @ tyang1 Terima kasih atas perhatiannya, tetapi dokumen satu sinyal untuk panggilan balik itu (getPermissionSubscriptionState) mengatakan:

Screen Shot 2021-02-22 at 09 07 47

Saya akan menguji dengan addSubscriptionObserver dan akan memberi tahu Anda apa yang terjadi

Mendapatkan ini juga. Tidak tahu cara mereproduksi. @rgomezp mungkin ini masalah threading? Ini terjadi secara acak, tetapi cukup banyak. Kami melihat banyak jejak dalam laporan kerusakan kami

image

apa kabar,
Saya tidak berpikir ini adalah masalah threading karena jejak tumpukan mengarah ke sana lebih mungkin terjadi di tingkat pembungkus. Ini tentu bisa menjadi bug. Kami hanya membutuhkan langkah-langkah reproduksi yang dapat diandalkan untuk bergerak maju dengan resolusi.

Sangat menarik @renatobentorocha bahwa Anda melaporkan itu terjadi 98% di latar belakang.

@oferRounds @dijinshopwise apakah ini sesuatu yang juga Anda lihat?

+1

image

@rgomezp ikuti kodenya:

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) {
                //
            });
        }

        // ...
}

Saya menurunkan versi ke versi lama dan Google Play memperingatkan tentang kesalahan yang sama.

com.geektime.rnonesignalandroid.RNOneSignal.getDeviceState

Ada saran? Ada solusi sementara?

Kami masih menerima ratusan kerusakan ini, ada berita?
image

@diego-paired solusi sementara kami adalah menunda panggilan ke getDeviceState() setelah OneSingal init (kami menambahkan penundaan 2 detik)

@diego-paired solusi sementara kami adalah menunda panggilan ke getDeviceState() setelah OneSingal init (kami menambahkan penundaan 2 detik)

terima kasih atas tipnya

Hai @renatobentorocha ,
Terima kasih telah berbagi kode dengan kami!
Kait useEffect di sini dapat dipanggil untuk menginisialisasi SDK dalam komponen Aplikasi utama. Ini pada dasarnya adalah panggilan async yang dipanggil segera setelah komponen dipasang, tetapi tidak ada status yang memeriksa apakah inisialisasi telah selesai.
</s> </s> </s> </s> </s>
Anda dapat menggunakan kait useState untuk menambahkan status guna memeriksa status init sebelum menampilkan layar Selamat Datang.
</s> </s> </s> </s> </s>
Rekomendasi lain, seperti yang disarankan oleh @rgomezp , adalah menjalankannya dalam panggilan balik ke addSubscriptionObserver (maaf karena saya berbicara terlalu cepat pada getPermissionSubscriptionState yang sudah tidak digunakan sebelumnya), yang akan menjamin bahwa SDK telah berhasil diinisialisasi sebelum mengakses status perangkat.
</s> </s> </s> </s> </s>
Beri tahu kami jika ini membantu menyelesaikan masalah,
</s> </s> </s> </s> </s>
Terima kasih

@diego-paired @dan-developer

Saya mengikuti saran @rgomezp dan crash, untuk saat ini, berhenti terjadi.

OneSignal.addSubscriptionObserver(() => {
    OneSignal.getDeviceState().then((deviceState) => {
      console.log({deviceState})
    });
  });

Menggunakan aplikasi pengujian , tambahkan kode ini ke tombol:

Situasi 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)
});
});

Log menunjukkan:

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

Namun saat menggunakan kode contoh yang disediakan di componentDidMount :

Situasi 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);
}

Log menunjukkan:

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 adalah skenario 1 perilaku yang diharapkan?

@diego-paired @renatobentorocha @dan-developer dapatkah Anda membagikan contoh Anda atau mengonfirmasi jika kedua situasi di atas adalah yang Anda lihat?

Mohon dirinci bagaimana Anda menggunakan metode ini dan sertakan langkah-langkah untuk kami reproduksi.

@jfishman1 Lihatlah dokumentasi . Anda akan melihat bahwa getDeviceState adalah fungsi asinkron jadi pastikan untuk menunggunya, atau gunakan then .

Terlepas dari itu, tampaknya ada peluang bagus untuk menangani ini di SDK untuk menghindari kerusakan ini. Terima kasih telah muncul. Kami akan mengeksplorasi perubahan apa yang dapat dilakukan untuk menangani ini dengan lebih mulus.

Menggali ini sedikit lebih jauh, tampaknya penyebab yang paling mungkin adalah sisi asli mencoba untuk mendapatkan status perangkat sebelum konteks dimuat.

if (appContext == null) {
         logger.error("OneSignal.initWithContext has not been called. Could not get OSDeviceState");
         return null;
      }

sumber

Untuk mengonfirmasi, harap cari OneSignal.initWithContext has not been called. Could not get OSDeviceState di logcat asli Anda (misalnya: buka Android Studio).

Sementara itu, sepertinya kita bisa menambahkan tanda centang di jembatan Android untuk mencegah crash penuh.

Apapun, harap dicatat:
Kami tetap menyarankan hanya mendapatkan status perangkat melalui pengamat perubahan langganan untuk memastikan Anda tidak mendapatkan status perangkat terlalu dini

Terima kasih atas kesabaran kalian semua.


Dari #1085:
Alih-alih menunda pengambil status perangkat melalui timer, coba letakkan panggilan fungsi getDeviceState di pengamat langganan. Dengan cara ini, Anda akan tahu bahwa itu berlangganan. misalnya:

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
    }
});

Pembaruan: ini sekarang diperbaiki di versi terbaru 4.0.7

Saya memperbarui ke repo 4.0.7 terbaru. Saya tidak yakin apakah saya bertanya di tempat yang tepat tetapi pada beberapa simulator iOS dan perangkat Android saya bahkan hanya mendapatkan bidang ini dengan deviceState misalnya seperti ini. Bahkan tidak ada bidang userId.

{"rootTag":21,"initialProps":{}}
 WARN  {"hasNotificationPermission": false, "isEmailSubscribed": false, "isPushDisabled": false, "isSMSSubscribed": false, "isSubscribed": false, "notificationPermissionStatus": 0}
Apakah halaman ini membantu?
0 / 5 - 0 peringkat