1

using swift and firebase I have a list of data like so

{
"posts" : {
 "-KHbULJcKqt9bSpxNO9k" : {
  "author" : "Michele",
  "postText" : "tags as arrays?",
  "tag" : [ "HELLO", "WHAT'S UP?", "TEST" ]
}

with many more post. I want to search by tag and if a post contains the search term as a tag return the whole post. Ive been able to do this with strings using queryEqualToValue: but haven't been able to solve it for an array. Any point in the right direction is appreciated thank you.

This is what my save function looks like

func createNewPost(post: Dictionary<String, AnyObject>, tags: [String]) {
    let firebaseNewPost = POST_REF.childByAutoId()
    let firebaseTag = Firebase(url: "\(POST_REF)/\(firebaseNewPost.key)/tag")

    print(firebaseTag)


    firebaseNewPost.setValue(post)

    for tag in tags {
        let tagID = firebaseTag.childByAutoId()

        tagID.setValue(tag)
    }
}

Now I need help with searching through the data and retrieving certain post based on what a user searches for. This is what I was using when it was just one tag and it was a just a string.

    func loadTaggedShit(searchTerm: String) {

    DataService.dataService.POST_REF.queryOrderedByChild("tag").queryEqualToValue(seachTerm).observeEventType(.ChildAdded, withBlock: { snapshot in
        self.posts = []

        if let snapshots = snapshot.children.allObjects as? [FDataSnapshot] {
            for snap in snapshots {
                if let postDictionary = snap.value as? Dictionary<String, AnyObject> {
                    let key = snap.key
                    let post = Post(key: key, dictionary: postDictionary)

                    self.posts.insert(post, atIndex: 0)
                }
            }
        }

        self.tableView.reloadData()


    })

}

also the data now looks like this

"posts":{
 "-KHj_bDJmZJut7knKoUX" : {
  "author" : "Michele",
  "postText" : "what's up",
  "tag" : {
    "-KHj_bDJmZJut7knKoUY" : "HEY"
   }
 }
}

1 Answer 1

1

Firebase arrays are very situational and really should be avoided if possible.

Array's in code are very powerful data constructs but they just don't work well within a JSON structure. If they are modified, say, removing a node, that index will be removed as well. That leaves the array with 'holes' e.g. 0, 1, 2, 4, 5, 7 etc. So, create yourself a tags child node within your post node, and then child nodes with keys created with childByAutoId

"posts" : {
 "-KHbULJcKqt9bSpxNO9k" : {
    "author" : "Michele",
    "postText" : "tags as arrays?",
    "tags"
       tag_id_0
         tag_title: "HELLO"
       tag_id_1
         tag_title: "WHAT'S UP?"
       tag_id_2
         tag_title: "TEST"
}

You might even consider creating a separate tags node and reference it within the posts node - especially if they are going to be re-usable.

Edit:

Based on some additional information, a different structure will be in order because the OP needs to query for posts that contain a specific tag and the tags are in fact reusable and not specific to a post:

posts
  -KHbULJcKqt9bSpxNO9k
    author: "Michele"
    postText: "tags as arrays?"
    tags
      tag_id_1: true
      tag_id_2: true
  -JPHJSojo91920LLK0J
    author: "Larry"
    postText: "NO, don't use arrays"
    tags
     tag_id_2: true

tags
  tag_id_0
    tag_title: "HELLO"
  tag_id_1
    tag_title: "WHAT'S UP?"
  tag_id_2
    tag_title: "TEST"

And then the code to receive all posts that use the TEST tag, tag_id_2

This is called a Firebase Deep Query

postsRef.queryOrderedByChild("tags/tag_id_2").queryEqualToValue(true)
        .observeSingleEventOfType(.Value, withBlock: { snapshot in
    print(snapshot)
})
Sign up to request clarification or add additional context in comments.

12 Comments

Thank you Jay the post are not going to be modified once the user has posted it so would that change how you would do this?
@Michi314 If they are specific to the post and will not be changed then use the Firebase structure I posted. That way they are query-able, loadable and are easy to work with in general
how would you go about saving the tags I tried but got the error no firebase namespace specified. This is the function that I made func createNewPost(post: Dictionary<String, AnyObject>, tags: [String]) { let firebaseNewPost = POST_REF.childByAutoId() let firebaseTag = Firebase(url: "(firebaseNewPost.key)/tags") firebaseNewPost.setValue(post) for tag in tags { let tagID = firebaseTag.childByAutoId() tagID.setValue(tag) } }
@Michi314 It's best practice to not post code in comments. The tag_is_0, tag_id_1 etc are nodes created with childByAutoId if that helps. Can you update your original question with your followup question?
sorry about that I just figured it out but i'll update it with my new code could you also help with querying the data and finding specific post? Thank you
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.