问题
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