Home > Software engineering >  How do I add data from a user in firebase rather than replace what is already there?
How do I add data from a user in firebase rather than replace what is already there?

Time:10-22

The app presents users with a random quote. I want users to be able to save the quotes and see which ones they saved. I can get a single quote to save, however, anytime the save button is clicked again, it overrides the previously saved quote with the new one. I've tried to find the answer elsewhere, but I cannot seem to get it to work. Below is my current code. I've also tried replacing setValue with updateChildValues, but I get the error Cannot convert value of type 'String' to expected argument type '[AnyHashable : Any]'.

import UIKit
import FirebaseDatabase
import FirebaseAuth

class QuotesViewController: UIViewController {

var ref: DatabaseReference?

override func viewDidLoad() {
    super.viewDidLoad()

    ref = Database.database().reference()
    
}

@IBAction func backToMain(_ sender: UIButton) {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let vc = storyboard.instantiateViewController(identifier: "mainHome")
        vc.modalPresentationStyle = .overFullScreen
        present(vc, animated: true)
}
@IBOutlet weak var quotesLabel: UILabel!
@IBAction func saveButton(_ sender: UIButton) {
    guard let user = Auth.auth().currentUser?.uid else { return }
    ref!.child("users").child(Auth.auth().currentUser!.uid).child("Quotes").child("quote").setValue(quotesLabel.text!)
    
}

@IBOutlet weak var nextButtonOutlet: UIButton!
@IBAction func nextQuoteButton(_ sender: UIButton) {
    
    let  quotesData = QuotesData()
    let randomQuote = quotesData.randomQuote()
    quotesLabel.text = randomQuote
      
}  
}

I've also tried:

ref!.child("users").child(Auth.auth().currentUser!.uid).child("Quotes").child("quote").updateChildValues(quotesLabel.text!)

CodePudding user response:

That is expected, you basically are referencing the very same node child("quote") and trying to change its value. But if you want to have multiple quotes, what you need to do is to create multiple nodes under the parent child("Quotes") with different names.

One trivial way of doing so, you might append a different number to each new quote node, for example when you want to add a new quote, define the following path:

child("Quotes").child("quote1").setValue("...")

Path for another quote:

child("Quotes").child("quote2").setValue("...") And so on.

Alternatively, you can use Firebase Database reference method childByAutoId() to generate unique names. You will use that method after defining the parent node:

ref!.child("users").child(Auth.auth().currentUser!.uid).child("Quotes").childByAutoId().setValue(quotesLabel.text!)


Note:

Try to avoid force unwrapping as much as you can because that makes your app more prone to crashes.

CodePudding user response:

I think you have to add one more field inside your firebase database that must be a unique one

For first time adding data into firebase you can write something like this

 let key = ref.child("Quotes").childByAutoId().key
    let dict = ["quote": quotesLabel.text!,
                "quoteId" : key ?? ""
    ] as [String: Any]
    

And whenever you are saving the same quote then you can update the value inside the particular quoteID like this

     func updateDatainFirebase(quoteId:String,quote:String){
        let dict = ["quote": quotesLabel.text!,
                    "quoteId" : quoteId ?? ""
        ] as [String: Any]
        self.ref.child(quoteId).updateChildValues(dict)
        
    }
    
  • Related