Upload Eureka form data to firebase

2020-07-26 11:50发布

问题:

I have a user profile that is an Eureka form view. In this space, users can update their profile. If the user clicks 'Save' it calls this function.

    func saveProfileSettings(){

    let userID = user?.uid
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd"

    let PROFILE_DISPLAY_NAME_REF: NameRow? = form.rowBy(tag: Constants.PROFILE_DISPLAY_NAME)
    let PROFILE_DISPLAY_NAME = PROFILE_DISPLAY_NAME_REF?.value

    let PROFILE_EMAIL_REF: EmailRow? = form.rowBy(tag: Constants.PROFILE_EMAIL)
    let PROFILE_EMAIL = PROFILE_EMAIL_REF?.value

    let PROFILE_PHONENUMBER_REF: PhoneRow? = form.rowBy(tag: Constants.PROFILE_PHONENUMBER)
    let PROFILE_PHONENUMBER = PROFILE_PHONENUMBER_REF?.value

    let PROFILE_BIRTH_AGE_REF: DateRow? = form.rowBy(tag: Constants.PROFILE_BIRTH_AGE)
    let PROFILE_BIRTH_AGE_CONVERT = PROFILE_BIRTH_AGE_REF?.value
    let PROFILE_BIRTH_AGE = formatter.string(from: PROFILE_BIRTH_AGE_CONVERT!)
    let PROFILE_BIRTH_AGE_String = String(PROFILE_BIRTH_AGE)

    let PROFILE_GENDER_REF: SegmentedRow<String>! = form.rowBy(tag: Constants.PROFILE_GENDER)
    let PROFILE_GENDER = PROFILE_GENDER_REF.value

    let PROFILE_GENDER_INTEREST_REF: SegmentedRow<String>! = form.rowBy(tag: Constants.PROFILE_GENDER_INTEREST)
    let PROFILE_GENDER_INTEREST = PROFILE_GENDER_INTEREST_REF.value

    let uploadPath = databaseRef.child("profiles").child(userID!)

    let dataBlock = ["\(Constants.PROFILE_DISPLAY_NAME)": PROFILE_DISPLAY_NAME!, "\(Constants.PROFILE_EMAIL)": PROFILE_EMAIL!, "\(Constants.PROFILE_PHONENUMBER)": PROFILE_PHONENUMBER!, "\(Constants.PROFILE_BIRTH_AGE)": PROFILE_BIRTH_AGE_String!, "\(Constants.PROFILE_GENDER)": PROFILE_GENDER!, "\(Constants.PROFILE_GENDER_INTEREST)": PROFILE_GENDER_INTEREST!]

    print("DataBlock \(dataBlock)")

    uploadPath.setValue(dataBlock) { (error, datebaseRef) in
        if error != nil{
            print("Error Occured")
        }
        print("Profile Updated!")
    }



}

This functions job is to pull all the data from the form, put it into an array and then upload it to firebase. If the user clicks save and doesnt update any information all is fine however if they edit their profile and clicks save it causes an error. See below.

assertion failed: Duplicate tag profileDisplayName: file /Users/brandonmayhew/Documents/Programming/X-Code Project's/ChristinaApp/Pods/Eureka/Source/Core/BaseRow.swift, line 172
2017-08-21 12:19:19.258586-0700 ChristinaApp[2615:926887] assertion failed: Duplicate tag profileDisplayName: file /Users/brandonmayhew/Documents/Programming/X-Code Project's/ChristinaApp/Pods/Eureka/Source/Core/BaseRow.swift, line 172

If you want to see what the code is for creating the form it is in my 'viewDidLoad'

override func viewDidLoad() {
    super.viewDidLoad()

    self.startAnimating(Constants.animationSize, message: "Finding Your Profile", type: .ballZigZag)

    //findImageURL()


    //START

    let userID = user?.uid
    print("Logged in user: \(userID!)")


    databaseRef.child("profiles").child(userID!).observe(.value, with: { (snapshot) in


        let data = snapshot.value as? NSDictionary

        let PROFILE_DISPLAY_NAME = data?[Constants.PROFILE_DISPLAY_NAME] as? String
        let PROFILE_UID = data?[Constants.PROFILE_UID] as? String
        let PROFILE_IMAGE = data?[Constants.PROFILE_IMAGE] as? String
        let PROFILE_EMAIL = data?[Constants.PROFILE_EMAIL] as? String
        let PROFILE_PHONENUMBER = data?[Constants.PROFILE_PHONENUMBER] as? String
        let PROFILE_GENDER = data?[Constants.PROFILE_GENDER] as? String
        let PROFILE_GENDER_INTEREST = data?[Constants.PROFILE_GENDER_INTEREST] as? String
        let PROFILE_BIRTH_AGE = data?[Constants.PROFILE_BIRTH_AGE] as? String
        let PROFILE_LATITUDE = data?[Constants.PROFILE_LATITUDE] as? String
        let PROFILE_lONGITUDE = data?[Constants.PROFILE_lONGITUDE] as? String

        self.form +++ Section("Personal Information")

            <<< NameRow(){ row in

                row.title = "Name"
                row.placeholder = "Enter Name"
                row.value = PROFILE_DISPLAY_NAME
                row.tag = "\(Constants.PROFILE_DISPLAY_NAME)"

                }

            <<< EmailRow(){ row in

                row.title = "Email"
                row.placeholder = "Enter Email"
                row.value = PROFILE_EMAIL
                row.tag = "\(Constants.PROFILE_EMAIL)"

            }

            <<< PhoneRow(){ row in

                row.title = "Phone Number"
                row.placeholder = "Enter Phone Number"
                row.value = PROFILE_PHONENUMBER
                row.tag = "\(Constants.PROFILE_PHONENUMBER)"

            }

            <<< DateRow(){ row in
                row.title = "Your Birth Year"

                //Convert 'PROFILE_BIRTH_AGE' string to NSDATE
                let date = NSDate()
                let dateFormatter = DateFormatter()
                dateFormatter.dateFormat = "yyyy-MM-dd"
                let formattedDate = dateFormatter.date(from: PROFILE_BIRTH_AGE!)

                row.value = formattedDate
                row.tag = "\(Constants.PROFILE_BIRTH_AGE)"
            }



            +++ Section("Dating Settings")

            <<< SegmentedRow <String> (){ row in
                row.title = "I am"
                row.options = ["Male", "Female"]
                row.value = PROFILE_GENDER
                row.tag = "\(Constants.PROFILE_GENDER)"
            }

            <<< SegmentedRow <String> (){ row in
                row.title = "I'm interested in"
                row.options = ["Male", "Female"]
                row.value = PROFILE_GENDER_INTEREST
                row.tag = "\(Constants.PROFILE_GENDER_INTEREST)"
            }

            +++ Section("Save Profile")
            <<< ButtonRow() {
                $0.title = "Save"
                }
                .onCellSelection {  cell, row in

                    self.saveProfileSettings()

            }

            +++ Section("Come Back Later")
            <<< ButtonRow() {
                $0.title = "Sign Out"
                }
                .onCellSelection {  cell, row in

                    self.signOut()
            }




        self.stopAnimating()


    })

    //STOP


}

I can not figure out what is making this error occur!

回答1:

The issue you're facing is caused by adding rows or sections with the same tag String value. In Eureka Forms the tags for cells or even sections should be unique, so if you are adding 2 rows with the same tag this will cause the assert exception

You have this type of behaviour in several parts of your code but I will take the name row as example

 <<< NameRow(){ row in

                row.title = "Name"
                row.placeholder = "Enter Name"
                row.value = PROFILE_DISPLAY_NAME
                row.tag = "\(Constants.PROFILE_DISPLAY_NAME)"  

                }

as you can see row.tag = "\(Constants.PROFILE_DISPLAY_NAME)" this is the line causing the issue, I am assuming that Constants.PROFILE_DISPLAY_NAME is a String defined in some part of your project, this string don't change and when you are about to add your second result from this method

databaseRef.child("profiles").child(userID!).observe(.value, with: { (snapshot) in

your app crash because you are adding the Constants.PROFILE_DISPLAY_NAME by second time with the same value "profileDisplayName"

a way to fix this

As a possible solution for this issue, You can append a unique value for every user fetched let say userID

Fixed code for NameRow case

 <<< NameRow(){ row in

                row.title = "Name"
                row.placeholder = "Enter Name"
                row.value = PROFILE_DISPLAY_NAME
                row.tag = "\(Constants.PROFILE_DISPLAY_NAME)\(userID)"  

                }