1

I am writing an app, where a signed up user should be able to see which of his contacts have signed up, too. What is the most elegant way to do this?

enter image description here

I was planning to create an array of all locally saved email addresses extracted from the user's local iOS addressbook and create a query for those. Is there any better way to do this?

Edit: Is this actually possible without downloading the whole user list? I could use a for loop with queryStartingAtValue(emailAddress) and queryEndingAtValue(emailAddress). But this could possibly lead to hundreds of queries at the same time.

MJQZ1347
  • 2,607
  • 7
  • 27
  • 49
  • sign up you mean that also created an account? – Ymmanuel Jun 04 '16 at 14:40
  • Yes. A user creates an account and also stores his email and username as seen above in the database. – MJQZ1347 Jun 04 '16 at 14:42
  • this contacts list is local or is it saved in firebase? – Ymmanuel Jun 04 '16 at 14:45
  • I extract all email addresses from the user's iOS addressbook. Then I want to now which of those email addresses are already in my Firebase database. Hereby I could determine which contacts of the local user are using the app, too. – MJQZ1347 Jun 04 '16 at 14:49

2 Answers2

5

In NoSQL databases you'll often end up modeling the data in ways that your application wants to consume it.

In this case it seems your app needs to look up whether a user exists, based on their email address. For that purpose I'd add a list of email-to-uid data:

emailToUid
  "test@mail,com": "P0...wklsh1"
  "MJQZ1347": "Aj1278a..."

This is essentially a self-created index that allows you to check whether an email address is used without having to run a query.

Now you can loop over the contact and look whether there is a user for that email address with a:

ref.child("emailToUid").child(email).observeSingleEventOfType(.Value

This is going to be very fast. Because of the way Firebase communicates with the back-end, there's going to be very little difference between a single request with 100 email addresses or 100 requests with a single email address. See my answer here for more on that: Speed up fetching posts for my social network app by using query instead of observing a single event repeatedly

Community
  • 1
  • 1
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Thank you! This looks quite promising. Going to try it and then mark it as the accepted answer. – MJQZ1347 Jun 04 '16 at 16:45
  • Worked flawlessy. I also added rules so that "emailToUid" is not readable, but its children are, to prevent fetching a list of all registered email addresses. A single known email can still be checked for existence though: See Kato's answer here: http://stackoverflow.com/questions/22078531/how-to-find-out-if-an-email-is-already-registered-with-firebase-simple-login – MJQZ1347 Jun 04 '16 at 17:32
  • 1
    Cannot use email as key unfortunately. How did you get past this? – Jonathan Clark Jan 24 '17 at 14:17
  • @FrankvanPuffelen how do you index the email address – shakil.k Apr 12 '17 at 18:58
0

You could have something like this

user
  -$user_id
      -email
      -username
      -contacts 
        -contact_uid1:email1,
        -contact_uid2:email2,
        -contact_uid3:email3,

And then do:

  1. Download the contact child from firebase and save it to a var

  2. Create the loop to check every contact in the address book

  3. If the email is in the contact child don't do anything (it means you already verified the user once)

  4. If the email is not in the contact child launch a single event query to find the uid of an specific email

  5. in the callback of the query if it is nsnull the user is not in the app if the user exist, add the user to your contacts child node in firebase

This way you only launch the queries of the contacts you haven't checked

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Ymmanuel
  • 2,523
  • 13
  • 12