Send Form to users using Firebase Realtime-Database

▼魔方 西西 提交于 2020-08-10 19:16:17

问题


I am almost done fixing a huge problem I have been having the last few weeks. Long story short I'm trying to be able to send array data to my Firebase Database. I will show what the send button is currently sending when I press send:

I would like the zero to be every user's id (one node for each row). The number of users and who they are is determined by a table and the child values to be the values in the array.

Here is the code for the function that sends to 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)
    }
}

I can't seem to be able to reference the atIndexPath.row. Then I would use the UID from each cell to create a node and then have each indePath.row data append the children values.

What is the best course of action?

EDIT: Here is the struct for people:

import UIKit

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

and here is the table code:

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)
    }
  }
}

EDIT:

Here is an example of the array when there is 3 users:

 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"

回答1:


If this is your goal (as stated in your question)

I would like the zero to be the user's id

On this line

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

change the ending child node from this

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

to this

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

To expand a little, you should be using a dataSource array to back your tableView

var myDatasource = [Person]()

so if you have three people (using your structure)

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

So just iterate over the array, get the person and their uid and write the data. Something like this (don't copy paste, did this on my 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)
}



回答2:


It's all-but impossible to do this sort of thing in Firebase.

Change to Firestore.

It will take you a tiny fraction of the time.

It's always worth remembering that Firebase is "Absolutely amazing and incredible, but often totally useless."

There are mnany things you just can't realistically do in Firebase.

Making such architectural decisions is tough and critical.

Moreover, just change to an ordinary relational database for this.

You'll be done in a few minutes, it's so easy.

(Yes, sync is harder but it can be done. Just use PubNub or the like, or even Firebase raw "only as a syncer" to sync.)



来源:https://stackoverflow.com/questions/63289856/send-form-to-users-using-firebase-realtime-database

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!