添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account Attempt to invoke virtual method 'int java.lang.String.compareToIgnoreCase(java.lang.String)' on a null object reference #9556 Attempt to invoke virtual method 'int java.lang.String.compareToIgnoreCase(java.lang.String)' on a null object reference #9556 jd20 opened this issue Aug 4, 2020 · 15 comments · Fixed by #9582

🐛 Bug Report

Summary of Issue

When calling getContactsAsync() with sort set to firstName , I receive the following exception every time:

Possible Unhandled Promise Rejection (id: 3):
Error: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference

The cause appears to be that displayName on Contact is initialized to null, and if name is also null it will remain null. Then in the sort comparator, we do not verify that displayName is not null. This is in sortContactsBy method of ContactsModule.java.

Also, the exception will sometimes manifest as Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference instead.

Environment - output of expo diagnostics & the platform(s) you're targeting

Expo CLI 3.13.1 environment info:
System:
OS: macOS 10.15.2
Shell: 5.8 - /usr/local/bin/zsh
Binaries:
Node: 13.14.0 - ~/.nvm/versions/node/v13.14.0/bin/node
Yarn: 1.22.4 - /usr/local/bin/yarn
npm: 6.14.4 - ~/.nvm/versions/node/v13.14.0/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
IDEs:
Android Studio: 4.0 AI-193.6911.18.40.6626763
Xcode: 11.6/11E708 - /usr/bin/xcodebuild
npmPackages:
@sentry/react-native: ^1.6.1 => 1.6.1
@types/react: ^16.8.22 => 16.9.11
@types/react-native: 0.62.2 => 0.62.2
react: 16.11.0 => 16.11.0
react-native: 0.62.2 => 0.62.2

Steps to Reproduce

Reproduced on a Samsung A10, though I've also seen it occur on a variety of Samsung, Motorola, LG devices. To reproduce, do the following:

  • Create a contact with no name set (can have just phone number).
  • Make the following call to fetch and sort contacts:
  • await Contacts.getContactsAsync({
                    fields: [
                        'image',
                        'phoneNumbers',
                        'firstName',
                        'lastName',
                        'name',
                        'nickname',
                    pageOffset: offset,
                    pageSize: 100,
                    sort: 'firstName',
    

    Note: If you remove the sort parameter, then the exception will not be thrown.

    changed the title Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference Attempt to invoke virtual method 'int java.lang.String.compareToIgnoreCase(java.lang.String)' on a null object reference Aug 4, 2020

    When both firstName and lastName are null - they fall back to displayName.

    How did you create contact with null displayName too? Even if I create empty contact with only phone number - it's display name is set to that number.

    Is your no-name contact visible on Android built-in Contacts app?

    And which version of Expo SDK are you using?

    I still haven't found a way to create contact with all firstName, lastName and displayName being null. They're at least empty strings.

    Arabic should not be a reason, however you can paste here that name - I'll try it

    Oh okay, cool then. Actually, this issue only happens on one Android so far. It doesn't happen for two other Androids that I've tested. But then, I'm still a bit sceptical so that it doesn't happen in Production. But would this issue happen when the user's contacts have some weird names or something? I just wanna be sure

    It may be dependent on currently installed and used Android Contact app and how it saves contacts with no name. I tested it on two devices and two emulator API versions and couldn't reproduce, however I cannot deny possibility of catching null on any device. I'll think of securing it more.

    If you want to be sure that it never happens to your users, make a simple fallback - catch your promise rejection and try again without sorting. Then you can sort it on your own.

    @barthap I created the contact with just a phone number only, using the default Contacts app on Samsung. It doesn't even appear in the Contacts app after creating it (which brings up a dilemma of how to delete it).

    I've only seen the issue on Android, and mostly on Samsung devices, but I've also seen it for Pixel 3 XL and several Motorola devices (G4/G7/Z4).

    For now, I've just turned off the sort, as a work-around.

    Fixes #9556 There are rare situations, when Android Contacts app can save contact, which has all `firstName`, `lastName` and `displayName` fields being `null`. Expo Contacts module mostly handles these situations by falling back to empty strings, or taking the name from elsewhere (e.g. phone number, company name etc.), but there's a place where sorting by name can crash because of `NullPointerException`. # How `Contacts.getContactsAsync({ sort: 'firstName' }) //or 'lastName'` in order to sort, calls Java `Contact.getFirstName()` which in extreme cases returns `null`. Adding another null-check fixes the issue. Empty string is used as fallback, because initially all `Contact` fields are initialized this way. # Test Plan Tested with a few combinations of unnamed contacts.