Search code examples
javascriptfirebase-realtime-databasecordova-pluginsionic3angularfire2

Angularfire 2 equalTo query not working with variable value obtained from native phone contacts


I'm using the following: Ionic 3, Angularfire 2, usb connected iphone & Safari Developer console for native cordova testing (for full context).

The goal is to run through the numbers retrieved from the phone contacts and see if they exist in any of the Firebase /users/~user id string~/ ..then later do things if they do.

The brief issue outline is that my approach is returning empty arrays for each number, as though the Angularfire equalTo query is not getting passed a value from the variable being fed into it.

Firebase structure

- users
    - <user id string>
        - name:   "Some name"
        - number: "1234 56789"

Exported JSON example (not real names or numbers):

"users" : {

    "21JvDyuzNcbKTxGhCEyEzzSbwKc2" : {
      "name" : "Gary Oose",
      "number" : "1234 56789"
    },
    "F1AvstJCWqdzBWarXtxwcm01Ir02" : {
      "name" : "Tina Urtle",
      "number" : "987 654321"
    },
    "KNTJdnKaE3amJ79LOq40ztKWBWp2" : {
      "name" : "Tommy Adpole",
      "number" : "121 212 121"
    }

}

The code is as follows..

contacts.find(["name", "phoneNumbers"], {multiple: true, hasPhoneNumber: true}).then(contacts => {

    contacts.forEach((contact, index) => {

        if (contacts[index].phoneNumbers !== null) {

            var number_to_check = contacts[index].phoneNumbers[0].value;

            //var number_to_check = contacts[index].phoneNumbers[0].value;toString();
            //var number_to_check = "1234 56789";

            console.log("contact_obj number = ", number_to_check);                  

            let db_users_list = this.afDB.list(`/users/`,

                {
                    query: {
                        orderByChild: 'number',
                        equalTo: number_to_check
                    }
                }

            ).subscribe(number_matches => {

                console.log('number_matches ', number_matches);

                db_users_list.unsubscribe();

            });

        }

    });

}); 

Running the above code

When either of the following lines are used:

var number_to_check = contacts[index].phoneNumbers[0].value;

or

var number_to_check = contacts[index].phoneNumbers[0].value.toString();

(the latter as I wasn't sure if the console output was lying to me that it was returning a string)

..the first console.log in the code confirms that a number has been returned from the native phone contacts, such as:

[Log] contact_obj number = - "1234 56789‬"

.. but the second console.log returns an empty array, as though nothing has matched against the Firebase DB in the query (.. it returns the same log for every number returned from the loop):

[Log] number_matches  – [] (0)

The sanity check approach (..coffee's run out, I might be going mad)

When, instead of using either of the two lines above, I use the following line:

var number_to_check = "1234 56789";

(manually entering a static string value for the variable)

The first console.log returns the same number over and over, as expected seeing a static string value has been assigned to the number_to_check variable.

And the second console.log correctly returns an array for that number, indicating that the query has found a match for it in the Firebase DB, as seen below:

[Log] number_matches
Array (1)
0 {name: "Gary Oose", number: "1234 56789", $key: "21JvDyuzNcbKTxGhCEyEzzSbwKc2"}

So, does anyone have any pointers as to why the first approach (using the line of code below) is not working?

var number_to_check = contacts[index].phoneNumbers[0].value;

I get the feeling I'm missing something very obvious. Why would that changing variable not be getting picked up by the AngularFire equalTo query?


Solution

  • The issue is that there's sometimes whitespace in the string value the following line returns (from accessing the native phone's contact numbers):

    contacts[index].phoneNumbers[0].value;
    

    The solve is to remove the whitespace, like so:

    contacts[index].phoneNumbers[0].value.replace(/\s/g, '');
    

    Replace method found in a comment in Remove whitespaces inside a string in javascript

    I imagine the whitespace being present in some but not all of the numbers must be down to how the phone stores the contact numbers when they are added in different ways.. i.e. via a shared contact, manual entry, etc).

    With this solution in place I can successfully find the phone number matches (I also updated my Firebase number strings to be stored without spaces as well). As below..

    "users" : {
    
        "21JvDyuzNcbKTxGhCEyEzzSbwKc2" : {
          "name" : "Gary Oose",
          "number" : "123456789"
        },
        "F1AvstJCWqdzBWarXtxwcm01Ir02" : {
          "name" : "Tina Urtle",
          "number" : "987654321"
        },
        "KNTJdnKaE3amJ79LOq40ztKWBWp2" : {
          "name" : "Tommy Adpole",
          "number" : "121212121"
        }
    
    }
    

    If I wanted to keep the spaces in the number strings, I could have added a single space in the replace() to account for that.. replace(/\s/g, ' ')