get user name from firebase xcode - ios

Trying to get a user name from firebase and then displayed on a label.
Any help?
heres a sample of the code.
import Firebase
class HomeViewController: UIViewController {
#IBOutlet weak var userName: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
func getUserName(_ message:String) {
let uid = Auth.auth().currentUser?.uid
Database.database().reference().child("users").child(uid!).observeSingleEvent(of: .value, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
self.userName.text = dictionary["firstname"] as? String
}
})
}
}

Swift
let currentUserName = Auth.auth().currentUser?.displayName
print(currentUserName)

user.displayName It's in the firebase docs

You have To try this code...(After Authentication , You have to create display name ("Firstname + Lastname") inside mobile app using below mentioned code )
if let currentUser = Auth.auth().currentUser {
let changeRequest = currentUser.createProfileChangeRequest()
changeRequest.displayName = "Firstname" + "Lastname"
changeRequest.commitChanges(completion: { (error) in
if let error = error {
print("--> firebase user display name error:- ", error)
}
})
}
After completion of this code we got current user displayname.

Related

set user location with GeoFire in Xcode 10

My coding (as you will see) and familiarity with Xcode and Swift is basic, but I'm learning... I realize my nesting of the code isn't the greatest, if good at all. I am trying to integrate GeoFire within my Xcode 10 app. I have looked for a clear explanation, but I am still yet to find an answer. I have a registrationForm to register users. The initial Firebase setup was straightforward, and I have a fully functional form that registers the user in Firebase. Now I am trying to add GeoFire in order to track the user's location.
I have tried a bunch of approaches from YouTube videos and websites, none of which work.
import UIKit
import Foundation
import CoreLocation
import Firebase
import GeoFire
class SecondViewController: UIViewController {
//Firebase DB ref
var refDriver: DatabaseReference!
#IBOutlet weak var name: UITextField!
#IBOutlet weak var employeenumber: UITextField!
#IBOutlet weak var label: UILabel!
#IBAction func submit(_ sender: UIButton) {
addDriver()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//configuring firebase and ensures no error is returned
if(FirebaseApp.app() == nil){
FirebaseApp.configure()
}
//getting a reference to the node driver
refDriver = Database.database().reference().child("driver");
}
func addDriver(){
//generating a new key inside driver node
//and also getting the generated key
let key = refDriver.childByAutoId().key
//creating driver with the given values
let driver = ["id":key,
"name": name.text! as String,
"employeenumber": employeenumber.text! as String
]
//adding the driver to Firebase
refDriver.child(key!).setValue(driver)
//displaying submit message
label.text = "You are registered."
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
hey try importing the module after you install the pod
import GeoFire
**var geoFire: GeoFire?**
var myQuery: GFQuery?
in viewdidLoad() function call the setupGeofire()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
setupGeoFire()
}
func setupGeoFire() {
let geoFireRef = Database.database().reference().child("user_locations")
let geoFire = GeoFire(firebaseRef: geoFireRef)
self.geoFire = geoFire
loadUsersWithin(radius: 100)
}
in setupGeoFire i made a var geoFireRef this is just the node you want to save your users location info
let geoFireRef = Database.database().reference().child("user_locations")
then we make the geoFire object by passing in that node location, our geoFireRef var
then just making the geoFire object accessible everywhere using
``` self.geoFire = geoFire`` `
if you want to get users in a specific radius (km) you can check the func below too
func loadUsersWithin(radius: Double){
guard let uid = Auth.auth().currentUser?.uid else{return}
geoFire?.getLocationForKey(uid, withCallback: { (userLocation, err) in
guard let userLocation = userLocation else{return}
self.myQuery = self.geoFire?.query(at: userLocation, withRadius: radius)
self.myQuery?.observe(.keyEntered, with: { (key, location) in
if key == uid{
return
}
Database.database().reference().child("users").child(key).observeSingleEvent(of: .value, with: { (snapshot) in
guard let userDictionary = snapshot.value as? [String:Any] else{return}
let user = User(uid: key, dictionary: userDictionary)
self.user = user
self.usersArray.append(user)
self.nearbyCV.reloadData()
}, withCancel: { (err) in
print(err)
})
})
})
}
}
Here is my User.swift Data Model
import UIKit
class User{
var name: String
var userImgUrlString: String
var age: String
var uid: String
var aboutMeText:String
init(uid: String,dictionary: [String: Any]) {
self.name = dictionary["username"] as? String ?? ""
self.userImgUrlString = dictionary["profileImageUrlString"] as? String ?? ""
self.aboutMeText = dictionary["aboutMe"] as? String ?? ""
self.uid = uid
self.age = dictionary["age"] as? String ?? ""
}
}```
hope this helps yo it was hard to find info for me too when i just started but it gets better

Reading data from firebase in swift but not being able to display it. Possibly variable scope error [duplicate]

This question already has an answer here:
Returning data from function in Firebase observer code block swift
(1 answer)
Closed 4 years ago.
`
import UIKit
import FirebaseDatabase
import FirebaseAuth
class mapVC: UIViewController {
var name:String = ""
var number:String = ""
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.setHidesBackButton(true, animated:true);
var dict = fetchData()
print(dict)
}
func fetchData()->[String:String]{
var ref: DatabaseReference!
ref = Database.database().reference()
var uid:String=""
var email:String=""
let user = Auth.auth().currentUser
if let user = user {
let uid_local = user.uid
let email_local = user.email
uid=uid_local
email=email_local!
}
ref.child("Users").child(uid).observeSingleEvent(of: .value, with: { (snapshot) in
let value = snapshot.value as? NSDictionary
self.name = value?["name"] as? String ?? ""
print(value?["name"] as? String ?? "")
self.number = value?["number"] as? String ?? ""
print(value?["number"] as? String ?? "")
})
return(["Name":name,"Number":number,"Email":email,"UID":uid]);
}
}
Reading data from firebase in Swift but not being able to display it. Possibly variable scope error. The output of print(value?["name"] as? String ?? "" is the expected result) but is not being assigned to the self.name variable. I believe this is a scope error but I don't know for sure yet. All and any help is greatly appreciated since I am comparitively new to iOS and Swift.
Because receiving data from Firebase is asynchronous task, you can't do it like this. You have to use completion handler for this.
First add completion handler as parameter of a function, also you don't need return type
func fetchData(_ completion: #escaping ([String:String]) -> ())
Then call completion when you receive your data
ref.child("Users").child(uid).observeSingleEvent(of: .value, with: { (snapshot) in
...
completion(["Name":name,"Number":number,"Email":email,"UID":uid])
})
now you have access to data from Firebase in closure of fetchData function
override func viewDidLoad() {
...
fetchData { dict in
print(dict)
}
}
Note: you won't have these data until receiving data from Firebase isn't done, so it takes some time

How to retrieve a variable from a Firebase Database in Swift

I am attempting to simply read into the database that is structured as stated below. I am attempting to read the user's "userType" and use it in the following if statements below. Any help is appreciated!
Swift Code:
// Create firebase reference and link to database
var dataRef : DatabaseReference?
dataRef = Database.database().reference()
let userID = Auth.auth().currentUser!.uid // Get the User's ID
// Gather user's type (Customer or Company)
/*Use this space to gather the user's type into some variable named currUserType*/
if (currUserType == "Customer"){
self.performSegue(withIdentifier: "LoginToCustomer", sender: self)
print("User: " + userID + " has been signed in!")
}
else if (currUserType == "Company"){
self.performSegue(withIdentifier: "LoginToHost", sender: self)
}
else{
self.showMessage(alertTitle: "Error",
alertMessage: "Please report the following error with a description of what lead to to the error.",
actionTitle: "Dismiss")
}
Database Structure:
"Users" : {
"ZFH0lFe1fIb5bwSO2Q95ektD33L2" : {
"email" : "cust#test.com",
"userType" : "Customer"
}
First take the ref like i have took below:
let dbRef = Database.database().reference().child("Users")
Then create model like i have created below:
class Users {
var email: String?
var userType: String?
init(email: String, userType: String) {
self.email = email
self.userType = userType
}
}
Then create completion Handler like i have created below:
func getUsersData(handler: #escaping (_ usersArray: [Users]) -> ()) {
var usersArray = [Users]()
dbRef.observe(.value) { (datasnapshot) in
guard let usersnapshot = datasnapshot.children.allObjects as? [DataSnapshot] else { return }
for user in usersnapshot {
let email = user.childSnapshot(forPath: "email").value as! String
let userType = user.childSnapshot(forPath: "userType").value as! String
let userObj = Users(email: email, userType: userType)
usersArray.append(userObj)
}
handler(usersArray)
}
}
simply call this function which returns the whole array of users.
Refrence https://firebase.google.com/docs/database/ios/read-and-write#reading_and_writing_data

adding a child to a child in Firebase Database with Swift

I am working with the following Firebase Database:
I add new chatIDs with the following code:
DatabaseReference.users(uid: self.uid).reference().child("chatIds/\(chat.uid)").setValue(chat.uid)
I need to add a single child to the individual "chatIDs" that is a random string that I will generate but I haven't worked with Firebase for that long so I am not sure how to do add children this far in. How can I write the code to do this?
Based on your database structure, a possible implementation of you want would be:
let ref = Database.database().reference()
// Generating the chat id
let refChats = ref.child("chats")
let refChat = refChats.childByAutoId()
// Accessing the "chatIds branch" from a user based on
// his id
let currentUserId = self.uid
let refUsers = ref.child("users")
let refUser = refUsers.child(currentUserId)
let refUserChatIds = refUser.child("chatIds")
// Setting the new Chat Id key created before
// on the "chatIds branch"
let chatIdKey = refChat.key
let refUserChatId = refUserChatIds.child(chatIdKey)
refUserChatIds.setValue(chatIdKey)
I think what you're looking for is this
let key = firebaseRef.child("users").child("\(String(describing: uid))").child("chatIds").childByAutoId().key
let timestamp = Int(Date().timeIntervalSince1970)
let child = ["key":key,
"name": name as String,
"date": birth as String,
"created": "\(timestamp)"]
firebaseRef.child("users").child("\(String(describing: uid!))").child("chatIds").child(key).setValue(child)
as example I'm saving the key, name, date, and created, as Childs of chatIds, with the childByAutoId, that generates you a random key, so you can locate it when searching the object.
import UIKit
import Firebase
class ChatListVC: UIViewController {
var ref: FIRDatabaseReference!
var messages: [FIRDataSnapshot]! = []
fileprivate var _refHandle: FIRDatabaseHandle?
override func viewDidLoad() {
super.viewDidLoad()
self.userDetail()
}
func userDetail(){
_refHandle = self.ref.child("users").child("child id").observe(.value, with: { [weak self] (snapshot) -> Void in
guard let strongSelf = self else { return }
guard let dict = snapshot.value as? [String:Any] else { return }
//access data from dict
let MyName = dict["MyName"] as? String ?? ""
})
}

user Data are not showing in label

I am trying to display the user data in screen. But I always get an empty value. I don't know why.
var profileData = Profile(usrObj: [String:String]())
#IBOutlet weak var userName: UILabel!
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(true)
self.userName.text = profileData.FirstName
print(profileData.FirstName)
}
My print statement and my label value are empty. Please help me out with any mistake I am making.
My model class :
class Profile {
var FirstName: String
init(usrObj : [String: AnyObject]) {
self.FirstName = (usrObj["FirstName"] ?? "") as! String
}
var ProfileObject: [String:AnyObject] {
return ["FirstName" : self.FirstName]
}
In your LoginViewController save your data in NSUserDefaults
#IBAction func loginWithUserNamePassword(){
KRProgressHUD.show(progressHUDStyle: .White, message: "Loading...")
loginWithMailAndPassword((username.text?.trimWhiteSpace)!, password: (password.text?.trimWhiteSpace)!) { (user, error) in
if error != nil{
KRProgressHUD.dismiss()
SCLAlertView().showError("Login Error", subTitle: error!.localizedDescription)
}
else {
if user!.emailVerified
{
currentUser = user
fireBaseRef.child("Users").child(currentUser!.uid).child("UserProfile").observeSingleEventOfType(.Value, withBlock: { (snapshot) in
if let data: [String : AnyObject] = snapshot.value as? [String : AnyObject] {
let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setObject(data, forKey: "userdata")
userDefaults.synchronize()
enableSync()
self.navigateToNextScreen()
}
else{
}
})
}
else
{
SCLAlertView().showError("Login Error", subTitle: "This email is has not been verified yet")
}
}
}
}
and use that data in UserStaticDataViewController
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(true)
self.profileDetailsExists = true
let userdata : NSDictionary = NSUserDefaults.standardUserDefaults().valueForKey("userdata") as! NSDictionary
print(userdata["City"] as? String)
self.userName.text = userdata["FirstName"] as? String
self.userCity!.text = userdata["City"] as? String
self.userCountry!.text = userdata.valueForKey("Country") as? String
self.userState.text = userdata.valueForKey("State") as? String
self.userMobileNo.text = userdata.valueForKey("Mobile") as? String
self.userGmail.text = userdata.valueForKey("Email") as? String
self.userDob.text = userdata.valueForKey("DateOfBirth") as? String
}
Output:
Just approve my answer and give vote.
Happy coding.
From the fact that your print statement is empty, it means that the userObject you pass into the following equation
var profileData = Profile(usrObj: [String:String]())
probably does not have a string value for the key "firstName".
You can try to verify this by changing your code
self.FirstName = (usrObj["FirstName"] ?? "") as! String
to
self.FirstName = (usrObj["FirstName"] ?? "Hello world") as! String
and see if "Hello world" is printed out in your console.
If yes, then you just have to make sure that the "user" object you pass into the init function of Profile class should be a dictionary where a value is stored for the key "FirstName"

Resources