【问题标题】:How do I search for a particular item in my database using Swift and Firebase?如何使用 Swift 和 Firebase 在我的数据库中搜索特定项目?
【发布时间】:2019-01-26 11:37:24
【问题描述】:

所以我正在构建一个应用程序,在其中将某些单词添加到我的 Firebase 数据库中。当用户输入他们想要添加的单词时,我想检查该单词是否已经存在于数据库中。如果是这样,我会显示一个警报。如果没有,我会把它添加到数据库中。我将如何使用 Swift 做到这一点?任何帮助,将不胜感激。谢谢!

这是数据库结构:

speaktext-6-----
  wordList
    -LWQObIw1PKWJ_B9jNfp
       word: "Water"
       wordType: "Noun"

【问题讨论】:

  • 您能否包含您的 Firebase 结构,因为这将确定准确的答案。请将其作为文本包含,不要图像。
  • @Jay 我用数据结构更新了问题。我希望这是你所要求的。非常感谢您的帮助!
  • @Jay 我让它工作了!感谢古斯塔沃·沃尔布雷希特。也非常感谢您的意见!

标签: ios swift database xcode firebase


【解决方案1】:

您需要考虑到可能存在大量单词,因此加载所有单词不仅会很慢,因为它们必须加载然后迭代才能找到您要查找的单词,而且可能也会使设备内存不堪重负。

一个简单的解决方案是 Firebase 查询 - 让 Firebase 完成繁重的工作并返回您想要的节点。它会快很多并且不会压倒设备。

这是一个函数,它会告诉你一个单词是否存在于你的 firebase 结构中

func findWord(aWord: String) {
    let ref = self.ref.child("wordList")
    let query = ref.queryOrdered(byChild: "word").queryEqual(toValue: aWord)
    query.observeSingleEvent(of: .value, with: { snapshot in
        if snapshot.exists() {
            print("found the word")
            //you could expand on this to indicate it was a Noun etc
        } else {
            print("\(aWord) is not in the wordList")
        }
    })
}

同时查看Firebase Sorting and Filtering Data Guide

*假设结构为

root
  wordList
    word_id_0  //created with .childByAutoId
       word: "Water"

【讨论】:

  • 嘿。感谢您提供有效的解决方案。我实现了这个,但我遇到了一个错误。描述如下:线程 1:致命错误:在展开可选值时意外发现 nil。错误出现在您在答案中编写的代码的第 2 行(即 let ref = self.ref.child("wordList")。您也可以在这里帮助我吗?非常感谢!
  • 那是因为他用的是类引用,你可以把self换成Database.database().reference()
  • @ojassethi Gustavo 是正确的 - 我设置了一个引用我的 Firebase 的类 var - 所以从那时起,我可以使用 self.ref 而不是输入 let reference = Database.database ().reference(). 每次。
  • 我在函数中创建了一个新变量,它提供对 wordList 表的引用并且它起作用了。非常感谢你们俩!这对我帮助很大。
【解决方案2】:

您只需对单词 child 发出单个事件请求,然后您可以验证它是否.exists(),如果它在那里,它将返回。

let reference = Database.database().reference().child(<#child#>).child(<#Word#>)

reference.observeSingleEvent(of: .value, with: { (snapshot) in

    if snapshot.exists() {
        // handle word existing in database, show alert.
    } else {
        // handle word not existing in database, make a request to set the word in database.
    }
})

根据您的 cmets,您想遍历孩子的每个元素,您可以这样做:

let reference = Database.database().reference().child("wordList")

reference.observeSingleEvent(of: .value, with: { (snapshot) in

    if let words = snapshot.value as? [String : [String : Any]] {
            for word in words {
                if let currentWord = word.value["word"] as? String {
                    if currentWord == "YOUR WORD HERE" {
                        // handle word in database.
                        return
                    }
                }
            }

            // handle word NOT in database.

    } else {
        // handle empty array.
    }
})

【讨论】:

  • 嘿!感谢您的回复。我试过这样做,但它仍然没有将这个词与数据库进行比较。这是我写的代码:'func checkIfWordExists() { let reference = Database.database().reference().child("wordList").child("Word").child(wordTextField.text!) reference.observeSingleEvent( of: .value) { (snapshot) in if snapshot.exists() { self.displayAlert(title: "Error", message: "Word 已经存在。", buttonMessage: "Okay") } else { self.addWordToDatabase() } } }'
  • 看看你的造型,确保你看对了孩子,你最深的应该是这个词。还要确保 textField.text 正是您数据库中的单词。
  • 我正在尝试这样做。我有数据库 URL,它是数据库参考。然后我有一个名为“wordList”的表。然后我有带有 autoID 的元素。每个 autoID 元素包含两个字段,称为“Word”和“wordType”。我有适合这个模型的代码吗?非常感谢您的帮助!
  • 不,如果您通过 autoID 有孩子,那么访问他们的唯一方法就是拥有他们的 ID,或者遍历 wordList 上的每个元素
  • 哦。这解释了很多。我如何让它通过每个元素?再次感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-22
  • 2021-11-01
  • 1970-01-01
相关资源
最近更新 更多