Pushing information to firebase after event is cre

2020-05-07 05:54发布

I am trying to create an app where the user can look at a list of events, decide which one they want to join, click on that specific event, and then join it. The part I am trying to solve is that the person who creates the event wants to see which people joined it. I know how to get the people's email, but dont know how to push it to firebase in that specific event.

This is not using Firestore

Someone creates an event: enter image description here

Then other people see that event in a table view: enter image description here

Then the user can click on an event to get more information: enter image description here

What I want to do now is when people register for an event, I want to save their email and push it to firebase, where it will be part of this event: enter image description here

For further clarification, this is the code I use to push the events details to firebase:

@IBAction func registerEvent(_ sender: UIButton) {
    //push stuff to firebase
    let eventName = eventTitle.text!
    let eventDB = Database.database().reference().child("Events")
    let eventDict = ["EventTitle": eventTitle.text!, "numPeople": numberOfPeople.text!, "EventDescription": EventDescription.text!]

    eventDB.child(eventName).setValue(eventDict){
        (error, reference) in
        if(error != nil){
            print(error!)
        }
    }

}

I need to push the email of a user who registers for an event to the firebase database, but this action needs to take place in a different viewcontroller

Please let me know if I need to clarify more

2条回答
够拽才男人
2楼-- · 2020-05-07 06:47

The question is a bit vague but the first issue is using the event name as the documentID (key) to the event. While on the surface it seems like a good idea, it will end up being hard to maintain and difficult to change because documentID's (keys) cannot be changed. For example, If you name the event

Forth Of July Big Bash

and then a few days later you decide to change it to

Forth Of July Big Bash 2019

You can't. You will have to read in the node, delete the existing node and re-write it out. Additionally, every single other place in your database that references that node will also have to be read in, deleted and read back out.

One flexible option is this structure

Events //collection
   document_0 //a document within the collection
      event_name: "My Event"
      num_people: 10
      event_date: "20190704"
      registration //a collection
           doc_0:
               email: some email
           doc_1:
               email: another email

Now you can change the event name and will be much better for queries. It's often a good idea to disassociate documentID's from the data they contain.

Now to answer the question;

Firestore documents all have a documentID, that's whats used to uniquely identify one document from another. When reading in events, you want to keep track of that documentID within a class or structure, along with the rest of the fields.

For example - suppose we have events stored in our Firestore with the above structure and those are displayed in a tableView. You may have a class that stores each event as it's read from Firestore and a class var array that's used as a datasource for your tableView.

class EventClass { //this is the class that holds the events for the array
   var eventDocumentId = ""
   var eventName = ""
   var eventDate = ""
   var numPeople = ""
}

class ViewController: NSViewController {
   var myEventArray = [EventClass]()

   func createEvent() {
        let eventCollection = self.db.collection("Events")
        let eventName = "July 4th Big Bash"
        let eventDate = "20190704"
        let numPeople = "10"

        let eventDict = [
            "event_name": eventName,
            "event_date": eventDate,
            "num_people": numPeople
        ]

        //if there's an observer for the Event collection, this would fire
        //  passing in this event so an EventClass could be created
        //  and then added to the tableView dataSource.
        eventCollection.addDocument(data: eventDict)
   }

   func readEvents() {
       //Read events and populate the myEventArray with EventClasses
       //As each event is read in, create an EventClass and populate it
       // from the Firestore fields and also it's .documentID
   }

   func addAttendee() {
     let email = "test@thing.com" //attendee email address
     let docId = "cP3lXY5htLRqMGDZckv5" //get the documentID of the tapped event
     let eventCollection = self.db.collection("Events")
     let eventRef = eventCollection.document(docId)
     let registrationRef = eventRef.collection("registration")
     let dict = [
         "email":email
     ]

     registrationRef.addDocument(data: dict)
   }

The general concept is when a user taps row 3 in the tableView, your app responds to that by reading the element in the dataSource array at row 3, which will be an EventClass. From there, get the documentID from that EventClass and add the attendee to Firestore.

查看更多
3楼-- · 2020-05-07 06:48

There are a couple of different ways to do this and it really depends on if you are using the Realtime Database or if you are using Firestore. The following information will be using Firestore.

1st: Configure your database and create a path for your events to be posted.

// Create a path to the events DB
let eventsDB = Firestore.firestore().collection("events") 

// It is helpful to initialize your object with an id that way you can get it later
let eventID = eventsDB.document().documentID 

// Initialize your event with the eventID as an identifier 
let event = Event(id: eventID, etc.....)

2nd: Publish the data to firestore

// Turn your event into a dictionary 
// Your class or struct should have a data representation
let eventData = event.jsonRepresentation

// Create a path to prepare to publish to firestore
let path = Firestore.firestore().collection("users").document(id)

// Set the data
path.setData(value) { (error) in
     if let error = error {
          // There was an error handle it here
          return
     }
    // Anything passed this points means the data has been set
}

Now when you fetch and serialize your data you can access the identifier property and update that specific document. Assuming your event has attendees which stores their firebase uid than you can reference their information depending on how you build the User model.

Step 3: Update event, if your event doesn't have an attending property create it. Also checkout firebase transactions here. I won't be using that here but it is a good resource. https://firebase.google.com/docs/firestore/manage-data/transactions#transactions

// Append the new attending user to the old event 
let newEvent = event.attendees.append("some_unique_id_goes_here")

// Create a path
let path = firestore.firestore().collection("events").document(newEvent.identifer)

// Update the document at that path
dbPath.setData([attendingKey: newEvent.attendees], merge: true) { (error) in
    if let e = error {
        // There was an error handle it here
        return
    }
        // It was updated successfully 
}
查看更多
登录 后发表回答