Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

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

[Android] Contacts showing twice #74

Closed
paintedbicycle opened this issue May 13, 2018 · 30 comments
Closed

[Android] Contacts showing twice #74

paintedbicycle opened this issue May 13, 2018 · 30 comments

Comments

@paintedbicycle
Copy link
Contributor

When I load contacts on Android, each contact shows up twice.

screen shot 2018-05-13 at 5 55 24 pm

@joshuapinter
Copy link
Owner

Can you post the raw object responses for each contact? I want to see what the ids and unique values are.

@paintedbicycle
Copy link
Contributor Author

paintedbicycle commented May 13, 2018

Yes, I'll fire it back up. I'm 90% sure the Android code from this library is returning the contacts twice somehow (rather than it being on the app side) - I've confirmed in both my app and the example app. One sec and I'll see what the full object logs out.

@paintedbicycle
Copy link
Contributor Author

paintedbicycle commented May 13, 2018

 [{ birthday: null,
        emailAddresses: [],
        identifier: '2',
        fullName: 'Tester McTestName',
        id: 2,
        displayName: 'Tester McTestName',
        postalAddresses: 
         [ { label: 'Home',
             formattedAddress: '123 Fake Street, Fake City, Fake State, M4K2K2, Canada',
             pobox: null,
             street: '123 Fake Street, Fake City, Fake State, M4K2K2, Canada',
             neighborhood: null,
             type: 'Home',
             city: null,
             state: null,
             region: null,
             postalCode: null,
             postcode: null,
             country: null,
             stringValue: '123 Fake Street, Fake City, Fake State, M4K2K2, Canada' } ],
        givenName: 'Tester',
        familyName: 'McTestName',
        middleName: null,
        suffix: null,
        prefix: null,
        note: null,
        phoneNumbers: [] },
      { birthday: null,
        emailAddresses: [],
        identifier: '2',
        fullName: 'Tester McTestName',
        id: 2,
        displayName: 'Tester McTestName',
        postalAddresses: 
         [ { label: 'Home',
             formattedAddress: '123 Fake Street, Fake City, Fake State, M4K2K2, Canada',
             pobox: null,
             street: '123 Fake Street, Fake City, Fake State, M4K2K2, Canada',
             neighborhood: null,
             type: 'Home',
             city: null,
             state: null,
             region: null,
             postalCode: null,
             postcode: null,
             country: null,
             stringValue: '123 Fake Street, Fake City, Fake State, M4K2K2, Canada' } ],
        givenName: 'Tester',
        familyName: 'McTestName',
        middleName: null,
        suffix: null,
        prefix: null,
        note: null,
        phoneNumbers: [] } ]

The above is from the example app (not my app)

@joshuapinter
Copy link
Owner

Weird. They have the same id values. You'd think Android would be smarter than return duplicate records.

I'm not seeing this on my ExampleApp. If you add another test Contact, do you get 4 contacts in total, 2 duplicates?

@paintedbicycle
Copy link
Contributor Author

You're not seeing this on your ExampleApp? So weird.

Yes, I'm seeing 4 contacts for 2 in both my app and my ExampleApp.

Are you running 8.0? I'm running 8.0 in emulator.

@joshuapinter
Copy link
Owner

No, it just shows up once for each Contact, just like in the example GIF in the README.

Running 8.1 (API 27) on the emulator. I added the contacts manually, but my contacts only have a name. That's it. Maybe it has to do with the Address. Try adding a new Contact with just a name and see if you get a duplicate as well.

@paintedbicycle
Copy link
Contributor Author

Lol, yup that's it.

screen shot 2018-05-13 at 6 36 35 pm

@joshuapinter
Copy link
Owner

Ack, okay, we'll have to figure this out.

@paintedbicycle
Copy link
Contributor Author

paintedbicycle commented May 13, 2018

It also applies to phone and email.

screen shot 2018-05-13 at 6 45 02 pm

@paintedbicycle
Copy link
Contributor Author

Interesting - if there are 2, it adds even another contact

screen shot 2018-05-13 at 6 47 51 pm

So it appears that each time you do those methods where you push new details onto the contact, it's actually returning another contact.

@joshuapinter
Copy link
Owner

Looks like a similar issue to expo/expo#877.

@paintedbicycle
Copy link
Contributor Author

paintedbicycle commented May 13, 2018

OK weird - I totally disagree with the admins of those two libraries that it should be handled in application code. I'm not sure the logic there. If I ask a library to return my contacts, how could I ever have expected it to turn duplicates? Why would 100 app developers all have to come up with a fix for one library? Seems weird.

This would also mean iOS and Android aren't returning the same thing...

@paintedbicycle
Copy link
Contributor Author

@joshuapinter
Copy link
Owner

I agree. I think the library should handle it. Either we need to modify the query in such a way that it doesn't return duplicate contacts or (more likely) we need to do some post-query processing that merges contacts together before returning over the bridge to React Native.

@paintedbicycle
Copy link
Contributor Author

I would have expected it to have progressively merged data into one object and return that. But yes before or after I don’t know. What would be faster? Is there a performance part of this?

@paintedbicycle
Copy link
Contributor Author

I wouldn't be surprised if that Wix one held some answers. I scanned it, but the Java is a bit over me, but they have each of the queries and metadata broken into sections

@joshuapinter
Copy link
Owner

You're probably right, merging as we go probably makes the most sense. Not sure about performance but it doesn't look like there's any other way. Frustrating that the Android SDK doesn't just handle this for us.

I wish I could spend a week dedicated to getting this all sorted but, alas, daytime job. :)

@paintedbicycle
Copy link
Contributor Author

Haha, yeah I understand. Only so much time. But putting a few hours here and there will get us there. I think if we can solve this one and the matching postal address formats between iOS and Android (#52) then this contact module will solve the headaches that many other fail to. Since iOS and Android will then return exactly the same thing across the board, it'll be pretty solid. I've tried 4 other libraries in my app and none of them offered complete parity.

Slowly filling in the other methods over time can wait. I can jump in and try to help out with some of them. But this one and #52 are out of my league.

@paintedbicycle
Copy link
Contributor Author

@joshuapinter
Copy link
Owner

Yup, that looks like processing it as you're looping through it. I think that's what we'll have to do. In our case I think we'll look at the identifier or id and if it already exists in our Array, just merge the records. it's not going to be easy, though, since we're dealing with all of those different attributes, not just the Name and Phone Numbers like in that StackOverflow example.

@paintedbicycle
Copy link
Contributor Author

Not to mention that we have to standardize the return object/array between iOS and Android

@paintedbicycle
Copy link
Contributor Author

You know what's interesting about this bug? Each of the duplicate contacts are identical. Yes, the IDs are the same, but if you look at the content, the content is also identical.

Original I assumed that each contact ID duplicate had different content (one with the phone number, one with the email address, one with the postalAddress). But no, it appears that they are all identical, meaning it should be as simple as returning only one of them - but it wouldn't matter which one. I'd imaging the first or last in the array.

We'd have to double check that this is true, but if so, it should be a LOT easier than we thought to fix this.

@joshuapinter
Copy link
Owner

joshuapinter commented May 16, 2018 via email

@paintedbicycle
Copy link
Contributor Author

Ok I did some more tests. I created several contacts:

  • Only Name - Shows Once
  • Only Phone - Two Duplicates
  • Only Email - Two Duplicates
  • Only Postal - Two Duplicates
  • PhoneAndEmail - Three Duplicates
  • Two Phones - Three Duplicates
  • Two Emails - Three Duplicates

So looks like what I found was true. You can safely just add only one of each of the IDs to the array before returning.

@joshuapinter
Copy link
Owner

And you confirmed that the "Duplicates" are equivalent? They have all of the same information?

@paintedbicycle
Copy link
Contributor Author

Yeah, but I only did so by eye.

The below array is not in one piece, I've pieced it together from a few, but you can give it a scan.

[ { birthday: null,
        emailAddresses: 
         [ { type: 'Home',
             label: 'Home',
             address: '[email protected]',
             value: '[email protected]' } ],
        identifier: '2',
        fullName: 'Tester OnlyEmail',
        id: 2,
        displayName: 'Tester OnlyEmail',
        postalAddresses: [],
        givenName: 'Tester',
        familyName: 'OnlyEmail',
        middleName: null,
        suffix: null,
        prefix: null,
        note: null,
        phoneNumbers: [] },
      { birthday: null,
        emailAddresses: 
         [ { type: 'Home',
             label: 'Home',
             address: '[email protected]',
             value: '[email protected]' } ],
        identifier: '2',
        fullName: 'Tester OnlyEmail',
        id: 2,
        displayName: 'Tester OnlyEmail',
        postalAddresses: [],
        givenName: 'Tester',
        familyName: 'OnlyEmail',
        middleName: null,
        suffix: null,
        prefix: null,
        note: null,
        phoneNumbers: [] },
      { birthday: null,
        emailAddresses: [],
        identifier: '1',
        fullName: 'Test OnlyName',
        id: 1,
        displayName: 'Test OnlyName',
        postalAddresses: [],
        givenName: 'Test',
        familyName: 'OnlyName',
        middleName: null,
        suffix: null,
        prefix: null,
        note: null,
        phoneNumbers: [] },
      { birthday: null,
        emailAddresses: [],
        identifier: '3',
        fullName: 'Tester OnlyPhone',
        id: 3,
        displayName: 'Tester OnlyPhone',
        postalAddresses: [],
        givenName: 'Tester',
        familyName: 'OnlyPhone',
        middleName: null,
        suffix: null,
        prefix: null,
        note: null,
        phoneNumbers: 
         [ { type: 'Mobile',
             label: 'Mobile',
             digits: null,
             stringValue: '(555) 555-5555' } ] },
      { birthday: null,
        emailAddresses: [],
        identifier: '3',
        fullName: 'Tester OnlyPhone',
        id: 3,
        displayName: 'Tester OnlyPhone',
        postalAddresses: [],
        givenName: 'Tester',
        familyName: 'OnlyPhone',
        middleName: null,
        suffix: null,
        prefix: null,
        note: null,
        phoneNumbers: 
         [ { type: 'Mobile',
             label: 'Mobile',
             digits: null,
             stringValue: '(555) 555-5555' } ] },
      { birthday: null,
        emailAddresses: [],
        identifier: '4',
        fullName: 'Tester OnlyPostal',
        id: 4,
        displayName: 'Tester OnlyPostal',
        postalAddresses: 
         [ { label: 'Home',
             formattedAddress: '1234 Fake Street, Toronto, Ontario, M4K2K2, Canada',
             pobox: null,
             street: '1234 Fake Street, Toronto, Ontario, M4K2K2, Canada',
             neighborhood: null,
             type: 'Home',
             city: null,
             state: null,
             region: null,
             postalCode: null,
             postcode: null,
             country: null,
             stringValue: '1234 Fake Street, Toronto, Ontario, M4K2K2, Canada' } ],
        givenName: 'Tester',
        familyName: 'OnlyPostal',
        middleName: null,
        suffix: null,
        prefix: null,
        note: null,
        phoneNumbers: [] },
      { birthday: null,
        emailAddresses: [],
        identifier: '4',
        fullName: 'Tester OnlyPostal',
        id: 4,
        displayName: 'Tester OnlyPostal',
        postalAddresses: 
         [ { label: 'Home',
             formattedAddress: '1234 Fake Street, Toronto, Ontario, M4K2K2, Canada',
             pobox: null,
             street: '1234 Fake Street, Toronto, Ontario, M4K2K2, Canada',
             neighborhood: null,
             type: 'Home',
             city: null,
             state: null,
             region: null,
             postalCode: null,
             postcode: null,
             country: null,
             stringValue: '1234 Fake Street, Toronto, Ontario, M4K2K2, Canada' } ],
        givenName: 'Tester',
        familyName: 'OnlyPostal',
        middleName: null,
        suffix: null,
        prefix: null,
        note: null,
        phoneNumbers: [] },
      { birthday: null,
        emailAddresses: 
         [ { type: 'Home',
             label: 'Home',
             address: '[email protected]',
             value: '[email protected]' } ],
        identifier: '5',
        fullName: 'Tester PhoneANDEmail',
        id: 5,
        displayName: 'Tester PhoneANDEmail',
        postalAddresses: [],
        givenName: 'Tester',
        familyName: 'PhoneANDEmail




        { birthday: null,
        emailAddresses: 
         [ { type: 'Home',
             label: 'Home',
             address: '[email protected]',
             value: '[email protected]' } ],
        identifier: '5',
        fullName: 'Tester PhoneANDEmail',
        id: 5,
        displayName: 'Tester PhoneANDEmail',
        postalAddresses: [],
        givenName: 'Tester',
        familyName: 'PhoneANDEmail',
        middleName: null,
        suffix: null,
        prefix: null,
        note: null,
        phoneNumbers: 
         [ { type: 'Mobile',
             label: 'Mobile',
             digits: null,
             stringValue: '(555) 555-5555' } ] },
      { birthday: null,
        emailAddresses: 
         [ { type: 'Home',
             label: 'Home',
             address: '[email protected]',
             value: '[email protected]' } ],
        identifier: '5',
        fullName: 'Tester PhoneANDEmail',
        id: 5,
        displayName: 'Tester PhoneANDEmail',
        postalAddresses: [],
        givenName: 'Tester',
        familyName: 'PhoneANDEmail',
        middleName: null,
        suffix: null,
        prefix: null,
        note: null,
        phoneNumbers: 
         [ { type: 'Mobile',
             label: 'Mobile',
             digits: null,
             stringValue: '(555) 555-5555' } ] },
      { birthday: null,
        emailAddresses: 
         [ { type: 'Home',
             label: 'Home',
             address: '[email protected]',
             value: '[email protected]' } ],
        identifier: '5',
        fullName: 'Tester PhoneANDEmail',
        id: 5,
        displayName: 'Tester PhoneANDEmail',
        postalAddresses: [],
        givenName: 'Tester',
        familyName: 'PhoneANDEmail',
        middleName: null,
        suffix: null,
        prefix: null,
        note: null,
        phoneNumbers: 
         [ { type: 'Mobile',
             label: 'Mobile',
             digits: null,
             stringValue: '(555) 555-5555' } ] },
      { birthday: null,
        emailAddresses: 
         [ { type: 'Home',
             label: 'Home',
             address: '[email protected]',
             value: '[email protected]' } ],
        identifier: '8',
        fullName: 'Tester PhoneEmailPostal',
        id: 8,
        displayName: 'Tester PhoneEmailPostal',
        postalAddresses: 
         [ { label: 'Home',
             formattedAddress: '123456 Fake Street, Boston, 90210, USA',
             pobox: null,
             street: '123456 Fake Street, Boston, 90210, USA',
             neighborhood: null,
             type: 'Home',
             city: null,
             state: null,
             region: null,
             postalCode: null,
             postcode: null,
             country: null,
             stringValue: '123456 Fake Street, Boston, 90210, USA' } ],
        givenName: 'Tester',
        familyName: 'PhoneEmailPostal',
        middleName: null,
        suffix: null,
        prefix: null,
        note: null,
        phoneNumbers: 
         [ { type: 'Mobile',
             label: 'Mobile',
             digits: null,
             stringValue: '(555) 555-5557' } ] },
      { birthday: null,
        emailAddresses: 
         [ { type: 'Home',
             label: 'Home',
             address: '[email protected]',
             value: '[email protected]' } ],
        identifier: '8',
        fullName: 'Tester PhoneEmailPostal',
        id: 8,
        displayName: 'Tester PhoneEmailPostal',
        postalAddresses: 
         [ { label: 'Home',
             formattedAddress: '123456 Fake Street, Boston, 90210, USA',
             pobox: null,
             street: '123456 Fake Street, Boston, 90210, USA',
             neighborhood: null,
             type: 'Home',
             city: null,
             state: null,
             region: null,
             postalCode: null,
             postcode: null,
             country: null,
             stringValue: '123456 Fake Street, Boston, 90210, USA' } ],
        givenName: 'Tester',
        familyName: 'PhoneEmailPostal',
        middleName: null,
        suffix: null,
        prefix: null,
        note: null,
        phoneNumbers: 
         [ { type: 'Mobile',
             label: 'Mobile',
             digits: null,
             stringValue: '(555) 555-5557' } ] },
      { birthday: null,
        emailAddresses: 
         [ { type: 'Home',
             label: 'Home',
             address: '[email protected]',
             value: '[email protected]' } ],
        identifier: '8',
        fullName: 'Tester PhoneEmailPostal',
        id: 8,
        displayName: 'Tester Pho



        { birthday: null,
        emailAddresses: 
         [ { type: 'Home',
             label: 'Home',
             address: '[email protected]',
             value: '[email protected]' },
           { type: 'Work',
             label: 'Work',
             address: '[email protected]',
             value: '[email protected]' } ],
        identifier: '7',
        fullName: 'Tester TwoEmails',
        id: 7,
        displayName: 'Tester TwoEmails',
        postalAddresses: [],
        givenName: 'Tester',
        familyName: 'TwoEmails',
        middleName: null,
        suffix: null,
        prefix: null,
        note: null,
        phoneNumbers: [] },
      { birthday: null,
        emailAddresses: 
         [ { type: 'Home',
             label: 'Home',
             address: '[email protected]',
             value: '[email protected]' },
           { type: 'Work',
             label: 'Work',
             address: '[email protected]',
             value: '[email protected]' } ],
        identifier: '7',
        fullName: 'Tester TwoEmails',
        id: 7,
        displayName: 'Tester TwoEmails',
        postalAddresses: [],
        givenName: 'Tester',
        familyName: 'TwoEmails',
        middleName: null,
        suffix: null,
        prefix: null,
        note: null,
        phoneNumbers: [] },
      { birthday: null,
        emailAddresses: 
         [ { type: 'Home',
             label: 'Home',
             address: '[email protected]',
             value: '[email protected]' },
           { type: 'Work',
             label: 'Work',
             address: '[email protected]',
             value: '[email protected]' } ],
        identifier: '7',
        fullName: 'Tester TwoEmails',
        id: 7,
        displayName: 'Tester TwoEmails',
        postalAddresses: [],
        givenName: 'Tester',
        familyName: 'TwoEmails',
        middleName: null,
        suffix: null,
        prefix: null,
        note: null,
        phoneNumbers: [] },
      { birthday: null,
        emailAddresses: [],
        identifier: '6',
        fullName: 'Tester TwoPhones',
        id: 6,
        displayName: 'Tester TwoPhones',
        postalAddresses: [],
        givenName: 'Tester',
        familyName: 'TwoPhones',
        middleName: null,
        suffix: null,
        prefix: null,
        note: null,
        phoneNumbers: 
         [ { type: 'Mobile',
             label: 'Mobile',
             digits: null,
             stringValue: '(555) 555-5555' },
           { type: 'Home',
             label: 'Home',
             digits: null,
             stringValue: '(555) 555-5555' } ] },
      { birthday: null,
        emailAddresses: [],
        identifier: '6',
        fullName: 'Tester TwoPhones',
        id: 6,
        displayName: 'Tester TwoPhones',
        postalAddresses: [],
        givenName: 'Tester',
        familyName: 'TwoPhones',
        middleName: null,
        suffix: null,
        prefix: null,
        note: null,
        phoneNumbers: 
         [ { type: 'Mobile',
             label: 'Mobile',
             digits: null,
             stringValue: '(555) 555-5555' },
           { type: 'Home',
             label: 'Home',
             digits: null,
             stringValue: '(555) 555-5555' } ] },
      { birthday: null,
        emailAddresses: [],
        identifier: '6',
        fullName: 'Tester TwoPhones',
        id: 6,
        displayName: 'Tester TwoPhones',
        postalAddresses: [],
        givenName: 'Tester',
        familyName: 'TwoPhones',
        middleName: null,
        suffix: null,
        prefix: null,
        note: null,
        phoneNumbers: 
         [ { type: 'Mobile',
             label: 'Mobile',
             digits: null,
             stringValue: '(555) 555-5555' },
           { type: 'Home',
             label: 'Home',
             digits: null,
             stringValue: '(555) 555-5555' } ] } ]

@joshuapinter
Copy link
Owner

Certainly looks like it! We'll see how it works in practice when we change this.

This will make it much easier! Great catch!

@joshuapinter
Copy link
Owner

This should be fixed now @paintedbicycle! Give it a shot and let me know how it works for you!

@joshuapinter joshuapinter reopened this May 17, 2018
@joshuapinter
Copy link
Owner

Close this Issue when you've confirmed it's working. Thanks.

@paintedbicycle
Copy link
Contributor Author

Looks good to me!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants