Lookup key inside array of object in Firebase

2020-08-02 06:01发布

问题:

In my app I need the functionality to look up contact info data to check if a user already exists in my database. As it's possible that a user has multiple email addresses I'm storing this data in a separate class called ContactInfo.

Now I want to query all objects and check if an email is contained in the emails array inside ContactInfo. Therefore I'm using the email as key, that's why it's URL encoded. However I can't figure out the right query to achieve this.


contactInfo

  • -KYd3pbZ7D--yX6B3HY8
    • emails
      • john%40gmail%2Ecom: true
      • john%40hotmail%2Ecom: true
    • firstname: John
    • lastname: Doe
  • -KYdUDoMVOdUmJ4I3jO-
    • emails
      • jane%40gmail%2Ecom: true
    • firstname: Jane
    • lastname: Doe

Based on that the top level of my database looks like this

回答1:

Using an email address as a key is probably not what you want to do.

email addresses change and are considered dynamic data - it's best practice not use dynamic data (something that may change) as a key as if it does change, everywhere it's referenced in your database would also have to be updated.

One possibility is to store multiple emails as such:

contactInfo
    -KYd3pbZ7D--yX6B3HY8
         firstname: "John"
         lastname: "Doe"
         main_email: "-JYJkjajisaiisd"

and then a separate node for all of the emails.

contact_emails
    -JYJkjajisaiisd
       email : "john@gmail.com"
       uid : "uid_0"
    -YJNlkokaosomdo
       email : "john@hotmail.com",
       uid : "uid_0"
    -Juiaisidiasda
       email : "frank@fmail.com",
       uid : "uid_3"

This structure is query-able, maintainable and avoids having to worry about parsing/storing special characters (email chars) as a key. You can store multiple emails per person and you can change their main email by just updating the main_email node within their contactInfo

To check for emails, use this query

    contactEmailsRef.queryOrdered(byChild:"email")
          .queryEqual(toValue: "john@hotmail.com")
          .observeSingleEvent(of: .value, with: { snapshot in

                print(snapshot)

    })

will result in this node being printed

-YJNlkokaosomdo
     email : "john@hotmail.com",
     uid : "uid_0"