【问题标题】:Send Form to users using Firebase Realtime-Database使用 Firebase 实时数据库向用户发送表单
【发布时间】:2020-11-27 02:04:33
【问题描述】:

我几乎解决了过去几周遇到的一个大问题。长话短说,我正在尝试将数组数据发送到我的 Firebase 数据库。当我按下发送时,我将显示发送按钮当前正在发送的内容:

我希望零成为每个用户的 ID(每行一个节点)。用户的数量和他们是谁由一个表确定,子值是数组中的值。

这是发送到 firebase 的函数的代码:

@IBAction func sendButtonTapped(_ sender: Any) {
    
    let companyNameC = companyNameTextFieldConsiderations.text!.trimmingCharacters(in: .whitespacesAndNewlines)
    let companyDescriptionC = companyDescriptionTextFieldConsiderations.text!.trimmingCharacters(in: .whitespacesAndNewlines)
    
    let today = Date()
    let formatter1 = DateFormatter()
    formatter1.dateFormat = "MMM d y"
    print(formatter1.string(from: today))
    let todaysDate = formatter1.string(from: today)
            
    let storageRef = Storage.storage().reference(forURL: "MY STORAGE URL HERE")
    let imageName = companyNameTextFieldConsiderations.text!
    let storageCompanyRef = storageRef.child("Company_Image_Considerations").child("\(todaysDate)").child(imageName)
    let companyDescriptionTextFieldText = companyDescriptionTextFieldConsiderations.text
    let dateToStart = startDateTextFieldConsiderations.text
    let dateToDecide = endDateTextFieldConsiderations.text
    let companyRef = Database.database().reference().child("Considerations").child("\(todaysDate)").child(imageName)
    let numberOfPeopleCells = ConsiderationsTestViewController.people
    let considerationInfluencerRef = Database.database().reference().child("Considerations").child("\(todaysDate)").child(imageName).child("Users").child("\(numberOfPeopleCells.startIndex)")
    
     let values = ["Feed_Quantity": "feedTFC", "Story_Quantity": "storyTFC", "Compensation": "compensationTFC"]
    
        guard let imageSelected = self.CompanyImage.image else {
            print ("Avatar is nil")
            return
                }
                   
                var dict: Dictionary<String, Any> = [
                    "Company Image": "",
                    "Company Description": companyDescriptionTextFieldText!,
                    "Start Date": dateToStart!,
                    "Decision Date": dateToDecide! ]
    
                   
        guard let imageData = imageSelected.jpegData(compressionQuality: 0.5) else {
            return
                }
    
                let metadata = StorageMetadata()
                metadata.contentType = "image/jpeg"
                storageCompanyRef.putData(imageData, metadata: metadata, completion:
                { (StorageMetadata, error) in
                if (error != nil) {
                return
                    }
                            
                storageCompanyRef.downloadURL { (url, error) in
                if let metadateImage = url?.absoluteString {
                dict["Company Image"] = metadateImage
                   
                companyRef.updateChildValues(dict, withCompletionBlock:  {
                (error, ref) in
                if error == nil {
                print("Done")
                return
                    }
                  }
                )
               }
             }
                            
                                   storageRef.updateMetadata(metadata) { metadata, error in
                                    if error != nil {
                                    //Uh-oh, an error occurred!
                                    } else {
                                    // Updated metadata for 'images/forest.jpg' is returned
                                }
                            }
                        })
    
    considerationInfluencerRef.updateChildValues(values as [AnyHashable : Any]) { (error, ref) in
    if error != nil {
    print(error ?? "")
    return
                       }
    
self.navigationController?.popViewController(animated: true)
    }
}

我似乎无法引用 atIndexPath.row。然后我会使用每个单元格中的 UID 创建一个节点,然后让每个 indePath.row 数据附加子值。

最好的做法是什么?

编辑:这是人的结构:

import UIKit

struct Person {
   var Name: String?
   var PostNumber: String?
   var StoryNumber: String?
   var Compensation: String?
   var ProfileImageUrl: String?
   var userID: String?
}

这是表格代码:

extension ConsiderationsTestViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    
    return ConsiderationsTestViewController.people.count
}

func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: AddPersonCell, for: indexPath) as! ConsiderationsCell
    
    let numberOfPeopleCells = ConsiderationsTestViewController.people[indexPath.row]
    
    
    cell.nameLabelC.text = numberOfPeopleCells.Name
    cell.feedLabelC.text = numberOfPeopleCells.PostNumber
    cell.storyLabelC.text = numberOfPeopleCells.StoryNumber
    cell.compensationLabelC.text = numberOfPeopleCells.Compensation
    cell.userImage.loadImageUsingCacheWithUrlString(urlString: numberOfPeopleCells.ProfileImageUrl!)
    
    cell.userImage.layer.cornerRadius = 25
    
    cell.nameLabelC.numberOfLines = 0
    
    return cell
}

func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    return true
}

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    if (editingStyle == .delete) {
        
        ConsiderationsTestViewController.people.remove(at: indexPath.row)
        // handle delete (by removing the data from your array and updating the tableview)
        tableView.deleteRows(at: [indexPath], with: .fade)
    }
  }
}

编辑:

下面是有 3 个用户时的数组示例:

 3 elements
 ▿ 0 : Person
 ▿ Name : Optional<String>
  - some : "Person's Name1"
 ▿ PostNumber : Optional<String>
  - some : "1"
 ▿ StoryNumber : Optional<String>
  - some : "1"
 ▿ Compensation : Optional<String>
  - some : "1"
 ▿ ProfileImageUrl : Optional<String>
  - some : "PROFILEIMAGE URL HERE"
 ▿ userID : Optional<String>
  - some : "B2Z4DlZ8RucvEQhz2NSUkquqc5P2"

 ▿ 1 : Person
 ▿ Name : Optional<String>
  - some : "Person's Name2"
 ▿ PostNumber : Optional<String>
  - some : "1"
 ▿ StoryNumber : Optional<String>
  - some : "11"
 ▿ Compensation : Optional<String>
  - some : "1"
 ▿ ProfileImageUrl : Optional<String>
  - some : "PROFILEIMAGE URL HERE"
 ▿ userID : Optional<String>
  - some : "Lbn9HL1WIpZTMFzpGWAXy7Ra0EA2"

 ▿ 2 : Person
 ▿ Name : Optional<String>
  - some : "Person's Name3"
 ▿ PostNumber : Optional<String>
  - some : "1"
 ▿ StoryNumber : Optional<String>
  - some : "1"
 ▿ Compensation : Optional<String>
  - some : "1"
 ▿ ProfileImageUrl : Optional<String>
  - some : "PROFILEIMAGE URL HERE"
 ▿ userID : Optional<String>
  - some : "NE6WVUfF6WQjJT9eeVSJgfvrrZW2"

【问题讨论】:

    标签: arrays swift firebase firebase-realtime-database


    【解决方案1】:

    如果这是您的目标(如您的问题所述)

    我希望零成为用户的 id

    在这条线上

    let considerationInfluencerRef = Database.database().reference().child("Considerations")
                               .child("\(todaysDate)")
                               .child(imageName)
                               .child("Users")
                               .child("\(numberOfPeopleCells.startIndex)")
    

    从此更改结束子节点

    .child("\(numberOfPeopleCells.startIndex)")
    

    到这里

    .child(Auth.auth().currentUser.uid)
    

    为了扩展一点,你应该使用一个 dataSource 数组来支持你的 tableView

    var myDatasource = [Person]()
    

    所以如果你有三个人(使用你的结构)

    myDatasource[0] = person 0
    myDatasource[1] = person 1
    myDatasource[2] = person 2
    

    所以只需遍历数组,获取人员及其 uid 并写入数据。像这样的东西(不要复制粘贴,这是在我的 iPad 上做的)

    myDatasource.forEach { person in
       let uid = person.userID
       let dict = [
          "name": person.name,
          "postNumber": person.postNumber
       ]
    
       let ref = let considerationInfluencerRef = Database.database().......child(uid)
       ref.setData(dict)
    }
    

    【讨论】:

    • 嘿,杰。这是我的错。我解释得不够清楚。我希望节点是表中的所有用户 uid。每行在该单元格的结构中都有一个用户及其 UID。
    • 模式是一样的。建立父节点后,所有写入的子数据都将写入该节点。我的答案显示了如何使用当前的 userId,但如果 id 存储在数组中,只需遍历该数组,从中读取每个 uid,制作父节点,如我的答案所示,然后写入子数据。
    • 我要使用的所有数据都在一个结构中。每个 indexPath.row 都有一个用户和与之相关的信息。在编辑区域中,它显示了数组的外观。不知道如何让users下的每个父节点,表中的所有用户。
    • 我向杰道歉。我不是要编辑你的答案。
    • @CoderCoop 我在答案中添加了更多代码。只需遍历 dataSource 数组,获取人员 uid,制作 ref 并存储 dict。这将导致每个子节点都以用户 uid 作为键,然后是您请求的子数据。
    【解决方案2】:

    在 Firebase 中做这种事情几乎是不可能的。

    更改为 Firestore。

    这将花费您一小部分时间。

    始终值得记住的是,Firebase “绝对令人惊叹和令人难以置信,但通常完全没用。”

    您在 Firebase 中实际上无法完成许多事情。

    做出这样的架构决策是艰难而关键的。

    另外,换成普通的关系型数据库即可。

    您将在几分钟内完成,非常简单。

    (是的,同步比较困难,但可以做到。只需使用 PubNub 等,甚至使用 Firebase raw“仅作为同步器”进行同步。)

    【讨论】:

    • 我不知道该怎么做。我的所有用户和所有东西都在我的存储中,并且必须重写这么多代码,因为我有一个消息传递功能,但我不知道如何将它送到 Firestore。还有另一种方法吗?我需要能够向表中的每个用户发送他们的行信息以及表外的信息。
    • @CoderCoop 我不确定我是否同意这个答案 - 主要是因为这个任务在实时数据库或 Firestore 中都很容易 - 也可以切换到 普通 本地关系数据库(MySQL?Posgresql?)将导致没有实时更新、内置用户身份验证、云功能、在线优先功能和许多其他功能。并不是说这是错误的,只是说由于问题的含糊不清,基于意见的答案可能会偏离基础:-)
    • @Jay - 顺便说一句,显然我的意思是使用 rdb .. MySql 非常棒在云中 ...正如你所知,这是非常广泛的可用,你可以旋转一个从这里单击 2 次,AWS 就是您所需要的。请注意我的最后一段(大括号中),它完全解释了 - 详细! - 这些天如何轻松同步。
    • @Jay,你说“这个任务很简单......” TBH我可能没有完全理解这个任务,因为解释有点长而且我掩饰了。
    • @CoderCoop - 你提到移动你的数据等。将需要 10-20 分钟.. 或者出现严重错误:/ 大幅加速开发的方法几乎总是一个“巨大的变化”.. .
    猜你喜欢
    • 2019-10-09
    • 2021-10-23
    • 1970-01-01
    • 2012-10-13
    • 2020-07-11
    • 2017-08-07
    • 2018-03-03
    • 1970-01-01
    • 2022-06-26
    相关资源
    最近更新 更多