【问题标题】:How to search for users in app? (the most cost efficient way) in Firebase如何在应用中搜索用户? (最具成本效益的方式)在 Firebase
【发布时间】:2018-10-23 07:45:48
【问题描述】:

我使用 firebase 制作了一个小型 MVP 测试应用。我还制作了一个用于搜索用户的 ViewController。但是现在,一旦单击 searchcontroller,我就必须加载 firebase 项目中的每个用户。这不是非常可扩展的。 (搜索控制器显示用户的用户名和个人资料照片。

我有它,所以用户必须在 searchcontroller 开始在 tableview 中显示内容之前输入至少两个单词。所以也许一个解决方案是只在点击时加载用户名,然后只在显示当前用户时加载个人资料图片?如果是这样,我该如何实现?

class FollowUsersTableViewController: UIViewController{

@IBOutlet var tableView: UITableView!

private var viewIsHiddenObserver: NSKeyValueObservation?
let searchController = UISearchController(searchResultsController: nil)
var usersArray = [UserModel]()
var filteredUsers = [UserModel]()
var loggedInUser: User?
//
var databaseRef = Database.database().reference()
//usikker på den koden over

override func viewDidLoad() {
    super.viewDidLoad()
    //large title
    self.title = "Discover"
    if #available(iOS 11.0, *) {
        self.navigationController?.navigationBar.prefersLargeTitles = true
    } else {
        // Fallback on earlier versions
    }

    self.tableView?.delegate = self
    self.tableView?.dataSource = self
    searchController.searchResultsUpdater = self
    searchController.dimsBackgroundDuringPresentation = false
    self.searchController.delegate = self;

    definesPresentationContext = true
    tableView.tableHeaderView = searchController.searchBar

    self.loadProfileData()
}

func loadProfileData() {
    databaseRef.child("profile").queryOrdered(byChild: "username").observe(.childAdded, with: { (snapshot) in
        print(snapshot)
        let userObj =  Mapper<UserModel>().map(JSONObject: snapshot.value!)
        userObj?.uid = snapshot.key

        guard snapshot.key != self.loggedInUser?.uid else { return }

        self.usersArray.append(userObj!)
    })
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    let dest = segue.destination as! UserProfileViewController
    let obj = sender as! UserModel
    let dict = ["uid": obj.uid!, "username": obj.username!, "photoURL": obj.photoURL, "bio": obj.bio]
    dest.selectedUser = dict as [String : Any]
}

  }

   // MARK: - tableview methods
   extension FollowUsersTableViewController: UITableViewDataSource, 
  UITableViewDelegate {

func tableView(_ tableView: UITableView, numberOfRowsInSection 
 section: Int) -> Int {
    return searchController.searchBar.text!.count >= 2 ? 
 filteredUsers.count : 0
  }

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! FollowTableViewCell

    let user = filteredUsers[indexPath.row]

    cell.title?.text = user.username
    if let url = URL(string: user.photoURL ?? "") {
        cell.userImage?.sd_setImage(with: url, placeholderImage: 
     #imageLiteral(resourceName: "user_male"), options: 
  .progressiveDownload, completed: nil)
        cell.userImage.sd_setIndicatorStyle(.gray)
        cell.userImage.sd_showActivityIndicatorView()
    }

    return cell
}

 func tableView(_ tableView: UITableView, heightForRowAt indexPath: 
   IndexPath) -> CGFloat {
    return 50
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: 
 IndexPath) {
    self.performSegue(withIdentifier: "user", sender: self.filteredUsers[indexPath.row])
}

 }

 // MARK: - search methods
 extension FollowUsersTableViewController:UISearchResultsUpdating, 
   UISearchControllerDelegate {

func updateSearchResults(for searchController: UISearchController) {
    searchController.searchResultsController?.view.isHidden = false
    filterContent(searchText: self.searchController.searchBar.text!)
    self.tableView.reloadData()
}

func filterContent(searchText:String){
    if searchText.count >= 2{
        self.filteredUsers = self.usersArray.filter{ user in
            return(user.username!.lowercased().contains(searchText.lowercased()))
        }
    }
   }
  }

【问题讨论】:

    标签: swift firebase firebase-realtime-database uisearchcontroller


    【解决方案1】:

    你可以使用queryStartingAtValue:

    func searchQueryUsers(text: String, completion: @escaping (_ userNames: [String]) -> Void) {
    
        var userNames: [String] = []
    
        databaseRef.child("profile").queryOrdered(byChild: "username").queryStarting(atValue: text).observeSingleEvent(of: .value, with: { snapshot in
    
            for item in snapshot.children {
    
                guard let item = item as? DataSnapshot else {
                    break
                }
    
                //"name" is a key for name in FirebaseDatabese model
                if let dict = item.value as? [String: Any], let name = dict["name"] as? String {
                    userNames.append(name)
                }
            }
    
            completion(userNames)
        })
    }
    

    【讨论】:

    • 谢谢老兄,但是“queryStarting(atValue: text)”你说的文本是什么意思?我还应该用你的 func searchQueryUsers 替换我的 func loadProfileData(),还是只添加 queryStarting atValue ?
    • "text" 这是您的用户名(或名称的一部分)。例如,名称 =“马特”-> 文本 =“马”。此外,您不需要下载所有用户数据,使用 queryStartingAtValue 代替 loadProfileData()
    • 但是这不加载个人资料图片?要不然是啥?你介意改变你的代码,以便我可以更清楚地看到它如何与我的变量和 jsonObject 用户模型映射器一起工作吗? (对不起,我是 firebase 新手,之前只使用过 aws)
    • 我也应该使用 searchController.searchBar.text 作为文本吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-12
    • 2019-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多