Slow synchronized loading of Contacts in ngCordova

#1

Hello,

I want to show contact list from my device and it works fine for 0 - 300 contacts. But I tested it on device with 800 contacts and it takes about 12 seconds. During this 12 seconds I can’t do anything except of showing $ionicLoading icon, because request to cordova doesn’t work asynchronously and I have to wait. I’d like to load contact list in background without 10s freezing. Is it possible somehow?
Btw it’s not problem with rendering contacts in template, but in cordova find function.

var options = {};
options.filter = "";
options.multiple = true;
options.fields = ['name.formatted', 'photos', 'emails'];

$cordovaContacts.find(options).then(function (result) {
    console.log("FIND");
}, function (error) {
    console.log("ERROR: " + error);
});
#2

I am running into same issue except that on Galaxy s1, 4.2.2 it takes about 24 seconds to load 700 contacts. However some of my users are not able to load any contacts it just hangs and never hides loading indicator. I was wondering if anyone saw a weird contact character or missing field that would cause the process of loading contacts to brake? Also the error callback is never called.

#3

It’s an android issue because of the way the cordova plugin queries the native contacts database.

I made a fork of the cordova-contacts-plugin that acepts a “hasPhoneNumber” param in the search options object. If set to true, the query will filter all the google contacts(gmail history etc…) and your app will have to deal with a much smaller contact list.

#4

thanks @jonmikelm , i will give it a try

#5

I’m having this issue as well. Contacts load instantly on iOS but take 8 seconds on my Nexus 5 with maybe 500 contacts. I’m worried this will be even longer on worse hardware or for more contacts.
Rendering isn’t an issue, I put timings in and the time is all spent actually retrieving the contacts in the $cordovaContacts.find call.

@jonmikelm I tried your plugin but found now improvement I’m afraid. I removed the standard plugin then added yours with:
cordova plugin add https://github.com/jonmikelm/cordova-plugin-contacts.git

var options = {};
options.multiple = true;
options.phoneNumberInformedOnly = true;

$cordovaContacts.find(options).then(onSuccess, onError).finally(function () {
         $scope.isloadingSpinnerVisible = false;
});

Did I do anything wrong?

#6

The upper comment in this forum post is a bit outdated. The new param was changed to “hasPhoneNumber”, it’s documented in the readme of the repository.

#7

The new “hasPhoneNumber” param has been merged to the official repo master branch. I recommend you to use the plugin from the official repo.

> ionic plugin rm cordova-plugin-contacts --save
> ionic plugin add https://github.com/apache/cordova-plugin-contacts --save

You’ll need to wait for the next plugin release to use the npm module “cordova-plugin-contacts”.

#8

If anyone is still struggling with slow load times for getting device contacts on Android, i recommend checking this out: https://github.com/dbaq/cordova-plugin-contacts-phone-numbers

I saw MAJOR performance improvement using this plugin - from 10-15 seconds, to about 1-2 seconds. I should mention that in my specific case I only need contacts with phone numbers, so this is the reason I am using this.

Also, based on issues on github, looks like he is working on integrating some filters, along with batch retrieval, so you can specify retrieval of contacts starting with “A” -> “C”, huge plus when dealing with thousands of contacts!

#9

In case anyone is still looking here for all cordova contacts.find speed issues, I found using the options parameter desiredFields to the contacts find function reduced a search that took over 10 seconds to under 1/2 a second, totally fixing the problem as I had it.

populateContacts: function () { var fields = ['']; var options = new ContactFindOptions(); options.filter=""; options.multiple=true; options.desiredFields=[navigator.contacts.fieldType.displayName, navigator.contacts.fieldType.name, navigator.contacts.fieldType.phoneNumbers]; var start = new Date(); navigator.contacts.find(fields, function (contacts) { var end = new Date(); alert(end.getTime() - start.getTime()); var cleanContacts = app.filterOnPhoneAndSortByNameAlphabet(contacts); cleanContacts.forEach(function (contact) { $.Deferred(app.processContact(contact)); }) }, function(contactError) { alert('error finding contacts'); }, options); }

I hope this helps.

3 Likes
#10

Any other advice on this? I’m on an iPhone 6 and it takes me about 10 seconds. During that time even the load spinner freezes.

I’m pulling all contacts
Then I alphabetize them
Then I push to database.

#11

Thanks a lot. jayber This helped. Was trying to get about 1200 contacts from a device and it was taking like 12 secs. Now it takes about 1 sec

#12

Get 3000 contacts from a emulator was taking 1min. Now it takes 5s.

Pass the fields that you want search. If you want find all, just pass the [navigator.contacts.fieldType.id] without option.filter like this:

navigator.contacts.find(
                    [navigator.contacts.fieldType.id],
                    onSuccess,
                    onError,
                    getOptions());
        function getOptions() {
            var options = new ContactFindOptions();
            options.multiple = true;
            options.desiredFields = [
                navigator.contacts.fieldType.displayName,
                navigator.contacts.fieldType.emails,
                navigator.contacts.fieldType.formatted,
                navigator.contacts.fieldType.givenName,
                navigator.contacts.fieldType.middleName,
                navigator.contacts.fieldType.name,
                navigator.contacts.fieldType.nickname,
                navigator.contacts.fieldType.phoneNumbers
            ];

            return options;
        }
#13

Hi jayber,

can u help me , how to use it with ionic 3.
Thanks alot.

#14

Hi Jayber,

How to implement this can you explained it