Can't get value of node in Firebase - ios

I read a lot examples and most of them have old style (even they are written current year). Please help understand where my code is wrong? It is built but I can't get a value 123456.
import UIKit
import Firebase
class ViewController: UIViewController {
#IBOutlet weak var val_txt: UITextField!
let ref = FIRDatabase.database().reference()
var barcode = 0
override func viewDidLoad() {
super.viewDidLoad()
FIRAuth.auth()?.signIn(withEmail: "*****#gmail.com", password: "*****", completion: {(user,error) in print("Авторизация Ок!!!")})
}
#IBAction func getData_btn(_ sender: Any) {
ref.child("goods").child("1").observe(FIRDataEventType.value, with: {(snapshot) in
let postDict = snapshot.value as? [String:AnyObject] ?? [:]
print(postDict["barcode"] as? Int)
})
print(barcode)
}
I've change code in order to understand Does print execute and I found that it doesn't
print("Method started")
ref.child("goods").child("1").observe(FIRDataEventType.value, with:{(snapshot) in
let postDict = snapshot.value as? [String:AnyObject] ?? [:]
print("Method is executing")
})
print("Method completed")
And I get just two rows of print
"Method started"
"Method completed"

If you want value only for "1":
var ref: FIRDatabaseReference!
ref = FIRDatabase.database().reference()
ref.child("goods").child("1").observeSingleEvent(of: .value, with: { (snapshot) in
let id = snapshot.childSnapshot(forPath: "barcode")
print(id)
})
but if you want all barcodes:
var ref: FIRDatabaseReference!
ref = FIRDatabase.database().reference()
ref.child("goods").observeSingleEvent(of: .value, with: { (snapshot) in
if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] {
for snap in snapshots
{
let barcode = snap.childSnapshot(forPath: "barcode").value! as! String
print(barcode)
}
}
})

In your code let ref = FIRDatabase.database().reference() do not Point to reference URL because during initialization your firebase not configure in your app delegate file (Not called FIRApp.configure()).
So put in func viewDidLoad() as follow:
import UIKit
import Firebase
class ViewController: UIViewController {
#IBOutlet weak var val_txt: UITextField!
let ref:FIRDatabaseReference!
var barcode = 0
override func viewDidLoad() {
super.viewDidLoad()
ref:FIRDatabaseReference = FIRDatabase.database().reference()
FIRAuth.auth()?.signIn(withEmail: "*****#gmail.com", password: "*****", completion: {(user,error) in print("Авторизация Ок!!!")})
}

Use below code it will help you.
let ref = FIRDatabase.database().reference()
ref.child("goods").child("1").observe(DataEventType.value, with: {(snapshot) in
if snapshot.childrenCount>0 {
for transactions in snapshot.children.allObjects as! [DataSnapshot] {
var obj = transactions.value as! [String:AnyObject]
print(obj["barcode"] as! Int)
}
}
})

Related

How to access Array created in closure?

I created scheduleDict1 and inserted it into scheduleArray1. I can only get the closure to "see" scheduleArray1 when it is declared in the closure as in the code now. However, I can't access scheduleArray1 anywhere other than the closure.
I have tried declaring the scheduleArray1 in the MainViewController class instead of the closure but it will not be seen inside the closure!
import UIKit
import Firebase
class MainViewController: UITableViewController {
// var scheduleArray1 = [[String: String]]()
var scheduleDict = [String: Any]()
override func viewDidLoad() {
super.viewDidLoad()
retrieveSchedule()
}
func retrieveSchedule(){
let ref = Database.database().reference(withPath: "squadrons/vt-9/2019-04-02/events/")
ref.observe(.value) { (snapshot) in
var scheduleArray1 = [[String: String]]()
var count = 0
let enumerator = snapshot.children
while let rest = enumerator.nextObject() {
let refToPost = Database.database().reference(withPath: "squadrons/vt-9/2019-04-02/events/" + "\(count)")
refToPost.observe(.value, with: { (snapshot) in
// let data = snapshot.children
let scheduleDict1 = snapshot.value as! [String: String]
scheduleArray1.append(scheduleDict1)
// self.print(scheduleArray1)
})
count += 1
}
}
}
}

TableView not displaying data from Firebase Database

I am building an app which uses Firebase's database service. I am trying to load the data into a table view but I am unable to do so. I can't seem to figure out what's going wrong. The code is also not giving me any errors. I've checked the database permissions on Firebase and they seem to be good. Here's my code:
import UIKit
import Firebase
struct postStruct {
let word : String!
let wordType : String!
}
class sentenceBuilderViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var wordSearchBar: UISearchBar!
#IBOutlet weak var wordsTableView: UITableView!
var posts = [postStruct]()
override func viewDidLoad() {
wordsTableView.reloadData()
getWordsFromDatabase()
super.viewDidLoad()
wordsTableView.delegate = self
wordsTableView.dataSource = self
}
func getWordsFromDatabase() {
let databaseRef = Database.database().reference()
databaseRef.child("wordList").queryOrderedByKey().observeSingleEvent(of: .childAdded, with: {
snapshot in
let word = (snapshot.value as? NSDictionary)!["word"] as? String
let wordType = (snapshot.value as? NSDictionary
)!["wordType"] as? String
self.posts.insert(postStruct(word: word, wordType: wordType), at: 0)
})
wordsTableView.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = wordsTableView.dequeueReusableCell(withIdentifier: "Cell")
let wordLabel = cell?.viewWithTag(1) as! UILabel
wordLabel.text = posts[indexPath.row].word
let wordTypeLabel = cell?.viewWithTag(2) as! UILabel
wordTypeLabel.text = posts[indexPath.row].wordType
return cell!
}
}
Any help and inputs would be appreciated! Thanks!
The problem is that you are just observing a single event here:
databaseRef.child("wordList").queryOrderedByKey().observeSingleEvent(of: .childAdded, with: {
snapshot in
What this does is that it justs goes through your database and once it finds any child, it displays that one without going further. What you need to do is change it to observe like this:
func getAllWordsFromDatabase() {
let databaseRef = Database.database().reference()
databaseRef.child("wordList").queryOrderedByKey().observe(.childAdded, with: {
snapshot in
let word = (snapshot.value as? NSDictionary)!["word"] as? String
let wordType = (snapshot.value as? NSDictionary)!["wordType"] as? String
self.posts.append(postStruct(word: word, wordType: wordType))
DispatchQueue.main.async {
self.wordsTableView.reloadData()
}
})
}
Try implementing this and it should work.
Move the "getWordsFromDatabase()" line in "viewDidLoad" function to AFTER you assign the delegate and data source, like this:
override func viewDidLoad() {
super.viewDidLoad()
wordsTableView.delegate = self
wordsTableView.dataSource = self
getWordsFromDatabase()
}
Also you can try to add a "reloadData()" method in the databaseRef block on the main queue, like this:
let databaseRef = Database.database().reference()
databaseRef.child("wordList").queryOrderedByKey().observeSingleEvent(of: .childAdded, with: {
snapshot in
let word = (snapshot.value as? NSDictionary)!["word"] as? String
let wordType = (snapshot.value as? NSDictionary
)!["wordType"] as? String
self.posts.insert(postStruct(word: word, wordType: wordType), at: 0)
DispatchQueue.main.async {
wordsTableView.reloadData()
}
})

My NSDictionary is becoming nil inside my IBAction

I have a tableview that presents events that a user creates. When you click on one of them it takes you to a different page that presents the details of the event.
I'm using Firebase and passing the postID from the tableview to the detailed view and all the information is being passed correctly in an NSDictionary.
However, when I try to access the NSDictionary out of the viewDidLoad and in an IBAction it tells me that the NSDictionary is nil. When I check in the viewDidLoad it is not nil.
I'm very new to programming and learning along the way but I've been stuck on this for a while now and have no idea whats wrong or how I can fix it
this is my code
import UIKit
import Firebase
class BeehiveViewViewController: UIViewController {
#IBOutlet weak var eventImage: UIImageView!
#IBOutlet weak var eventName: UILabel!
#IBOutlet weak var location: UILabel!
#IBOutlet weak var eventDate: UILabel!
#IBOutlet weak var eventHost: UILabel!
#IBOutlet weak var members: UILabel!
#IBOutlet weak var joinButton: roundButton!
var beehiveID: NSDictionary?
var ref = Database.database().reference()
override func viewDidLoad() {
super.viewDidLoad()
view.setGradientBackground(colourOne: primaryColor, colourTwo: secondaryColor)
let uid = Auth.auth().currentUser?.uid
ref.child("users").child(uid!).child(self.beehiveID?["pid"] as! String).observe(.value) { (snapshot) in
let uid = self.beehiveID!["pid"] as! String
self.beehiveID = snapshot.value as? NSDictionary
self.beehiveID?.setValue(uid, forKey: "pid")
}
let imageURL = self.beehiveID!["imageDownloadURL"] as! String
let url = URL(string: imageURL)
DispatchQueue.global(qos: .background).async {
let data = NSData(contentsOf: url!)
DispatchQueue.main.async {
self.eventImage.image = UIImage(data: data! as Data)
}
}
self.eventName.text = self.beehiveID?["eventName"] as? String
self.eventDate.text = self.beehiveID?["eventDate"] as? String
self.eventHost.text = self.beehiveID?["beehiveHost"] as? String
self.location.text = self.beehiveID?["location"] as? String
let uidd = Auth.auth().currentUser?.uid
Database.database().reference().child("users").child(uidd!).child("Posts").child(self.beehiveID?["pid"] as! String).child("Members").observe(.value) { (snapshot) in
let memberCount = snapshot.childrenCount
self.members.text = "\(memberCount)"
}
let userID = Auth.auth().currentUser?.uid
Database.database().reference().child("users").child(userID!).child("Posts").child(self.beehiveID?["pid"] as! String).observe(.value) { (snapshot) in
print(snapshot)
if (snapshot.exists()){
self.joinButton.setTitle("Remove Beehive", for: .normal)
}
else{
self.joinButton.setTitle("Join Beehive", for: .normal)
}
}
}
#IBAction func buttonPressed(_ sender: Any) {
if joinButton.titleLabel?.text == "Remove Beehive"{
let uid = Auth.auth().currentUser?.uid
let dbref = ref.child("users").child(uid!).child("Posts").child(beehiveID?["pid"] as! String)
//error is the line above that beehiveID?["pid"] is nil
dbref.removeValue()
navigationController?.popViewController(animated: true)
}
if joinButton.titleLabel?.text == "Join Beehive"{
let uid = Auth.auth().currentUser?.uid
let dbref = Database.database().reference().child("users").child(uid!).child("Posts").child("Members")
Database.database().reference().child("users").child(uid!).child("Name").observe(.value) { (nameSnapshot) in
let memberName = nameSnapshot.value as! String
let userObject = [memberName: uid]
dbref.updateChildValues(userObject as! [AnyHashable : String])
}
}
}
}
I assume that you're passing beeHive's value from the previous controller as you haven't initialised or got the values of it anywhere:-
Try having a breakpoint right before the end of viewDidLoad to double-check if the dictionary isn't nil at the block
self.beehiveID = snapshot.value as? NSDictionary
Try using a check to see if the snapshot's value is nil using 'if let' or 'guard' as you could possibly just be assigning a nil value to the NSDictionary. Also, since you're using optionals for assigning each value, it doesn't return an exception but just keeps assigning the nil value to every property
Do try this and let me know. Glad to help!

how do i get the value of self into the normal Variable

how can i get the value of self.valve1 from function readFireBaseData() into the function viewDidload() ??? i always get the set value of "valve1" which i set at the begining of the program. Hope someone can help me.
import UIKit
import FirebaseDatabase
import Firebase
class ValveViewController: UIViewController {
var valve1 = "OFF"
#IBOutlet var valveOne: UILabel!
override func viewDidLoad() {
readFirebaseData() //run the function readFireBaseData
let toggle = view.viewWithTag(1) as! UISwitch
if valve1 == "ON"
{
toggle.setOn(true, animated: true)
}else
{
toggle.setOn(false, animated: true)
}
super.viewDidLoad()
}//END of viewDidLoad
func readFirebaseData(){
var ref: DatabaseReference!
ref = Database.database().reference()
ref.child("switchValve").observeSingleEvent(of: .value, with: { (snapshot) in
let value = snapshot.value as? NSDictionary
self.valve1 = value?["valveOne"] as? String ?? ""
})
}//End of readFireBaseData
}//End of ViewController

TableView Public To all Users

I am creating a chat room app. Currently, when users signs in they are given their own table view to upload data too.
Instead of each user having their own personal table view I would like all users to be connected to one (public) table view so everyone can see what's posted. Hence a chat room app.
These are 3 separate logins and what it looks like for each user when they post a message:
This is what I want. To have each tableview cell represent a different message from a different user. All publicly viewed on one tableview. Not on separate table views:
How can I make the table view public? When I log in as a different user I would like the previous message to still be there from each user. Hence a chat room.
{
"rules": {
"Users":{
".read": "true",
".write": "true"
},
"general_room" : {
".read": "true",
".write": "true"
}
}
}
GeneralChatroom.swift
import UIKit
import Foundation
import Firebase
import FirebaseDatabase
import FirebaseStorage
struct postStruct {
let username : String!
let message : String!
let photoURL : String!
}
class GeneralChatroom: UIViewController, UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate {
#IBOutlet weak var messageTextField: UITextField!
var generalRoomDataArr = [postStruct]()
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 140
let ref = FIRDatabase.database().reference()
let userID = FIRAuth.auth()?.currentUser?.uid
ref.child("general_room").child("chat").child(userID!).queryOrderedByKey().observe(.childAdded, with: {snapshot in
let snapDict = snapshot.value as? NSDictionary
let username = snapDict?["Username"] as? String ?? ""
let message = snapDict?["Message"] as? String ?? ""
let firebaseUserPhotoURL = snapDict?["photo_url"] as? String ?? ""
self.generalRoomDataArr.insert(postStruct(username: username, message: message, photoURL: firebaseUserPhotoURL), at: 0)
self.tableView.reloadData()
})
}
#IBAction func backButtonPressed(_ sender: UIButton) {
self.performSegue(withIdentifier: "BackToRoom", sender: nil)
}
//Message Send button is pressed data uploaded to firebase
#IBAction func sendButtonPressed(_ sender: UIButton) {
let message : String = self.messageTextField.text!
UploadGeneralChatRoom(message: message) //upload to general_room
self.messageTextField.text = nil
messageTextField.resignFirstResponder()//Quit keyboard
self.tableView.reloadData() //Reload tableView
//UploadUserData() //Update Rank in database
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return generalRoomDataArr.count // your number of cell here
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")
let usernameLabel = cell?.viewWithTag(1) as! UILabel
usernameLabel.text = generalRoomDataArr[indexPath.row].username
let messageLabel = cell?.viewWithTag(2) as! UILabel
messageLabel.numberOfLines=0 // line wrap
messageLabel.lineBreakMode = NSLineBreakMode.byWordWrapping
messageLabel.text = generalRoomDataArr[indexPath.row].message
//initialize UI Profile Image
let imageView = cell?.viewWithTag(3) as! UIImageView
//Make Porfile Image Cirlce
imageView.layer.cornerRadius = imageView.frame.size.width/2
imageView.clipsToBounds = true
//User Profile image in tableview
if generalRoomDataArr[indexPath.row].photoURL != nil
{
//let imageView = cell?.viewWithTag(3) as! UIImageView
if let url = NSURL(string: generalRoomDataArr[indexPath.row].photoURL) {
if let data = NSData(contentsOf: url as URL) {
imageView.image = UIImage(data: data as Data)
}
}
}
// your cell coding
return cell!
}
}//END CLASS
Upload to firebase
import Foundation
import Firebase
import FirebaseDatabase
import FirebaseStorage
func UploadGeneralChatRoom(message : String) {
//Firebase Initialization
var ref: FIRDatabaseReference!
//var storage: FIRStorageReference!
let userID = FIRAuth.auth()?.currentUser?.uid
ref = FIRDatabase.database().reference()
//storage = FIRStorage.storage().reference()
//Get Data from database resend to database
ref.child("Users").child(userID!).observeSingleEvent(of: .value, with: {(snapshot) in
let snapDict = snapshot.value as? NSDictionary
let username = snapDict?["Username"] as? String ?? ""
let firebaseUserPhotoURL = snapDict?["photo_url"] as? String ?? ""
ref.child("general_room").child("chat").child(userID!).childByAutoId().setValue(["Username": username, "uid": userID!, "Message" : message, "photo_url" : firebaseUserPhotoURL])
})
}
I don't know how your firebase database is setup but you are posting to child("Users").child(userID!)
but reading from
child("general_room").child("chat").child(userID!)
You would need to read and write to the same location.
Also:
try to safely unwrap your optional values:
if let userId = userID {
ref.child("Users").child(userId).observeSingleEvent(of: .value, with: {(snapshot) in
let snapDict = snapshot.value as? NSDictionary
let username = snapDict?["Username"] as? String ?? ""
let firebaseUserPhotoURL = snapDict?["photo_url"] as? String ?? ""
ref.child("general_room").child("chat").child(userID!).childByAutoId().setValue(["Username": username, "uid": userID!, "Message" : message, "photo_url" : firebaseUserPhotoURL])
})
}

Resources