How to Handle Fetched User's Location from FBSDK IOS swift - ios

i got the user Location using FBSDK. Now I do not know how to seperate the information to get each part of information
i am printing it in console and this is what get
Optional({
id = 110855035610007;
name = "Rawalpindi, Pakistan";
})
how do i get "Rawalpindi" and "Pakistan" and store them in some variable
according to Docs its returning a Struct i guess so i do not know how to handle that please guide me thanks

First thing, you have to create one responseDictionary and then store response in it.
then you can get this name like,
let str = self.responseDic.valueForKey("name") as? String
Then you can separate this string like,
let arr : NSArray = str!.componentsSeparatedByString(",") as NSArray
print(arr.objectAtIndex(0))
print(arr.objectAtIndex(1))
Hope this way you will fix it.

Related

Retrieving user info from firebase

I know this question is asked a lot, but none of the solutions seem to be working for me(I have been trying multiple solutions from threads like Read data from firebase swift but it doesnt print anything to my console).
I am trying to retrieve the type of user from my database, but I dont know how to.
func pushUserInfo(){
let ref = Database.database().reference()
let infoDict = ["First name": firstName.text!, "Last name": lastName.text!, "hours": 0, "isUser" : "user"] as [String : Any]
let users = ref.child("users").child(username)
users.setValue(infoDict)
}
The part that says ["type": "user"] has two options, either "user" or admin
The screenshot above is of the Firebase realtime database.
I am trying to retrieve the type of the user, but I have no idea how. Please help me figure this out, and if possible, explain the code, because I dont really understand too much about Firebase in general. I tried reading their firebase docs, but I still dont really get it.
It looks like you're setting the data fine except that your username property appears to be a concatenated string of two optionals (maybe firstName.text and lastName.text. So this will make it impossible to query. The first step is to unwrap these into a string:
let username = "\(firstName.text!) \(lastName.text!)"
Once you've done that, you can query for that data like this:
let username = "\(firstName.text!) \(lastName.text!)"
let ref = Database.database().reference().child("users/\(username)")
ref.observeSingleEvent(of: .value, with: { (snapshot) in
// Now you can access the type value
let value = snapshot.value as? NSDictionary
let type = value?["type"] as? String ?? ""
}) { (error) in
print(error.localizedDescription)
}
You may also want to reconsider having spaces in your property names (maybe use lastName instead of last name). It will be easier for your code later on.

Swift Firebase -How to generate different .childByAutoId keys when using Fan Out

I have a chat system inside my app. When the user presses send to send the message data to different nodes inside the database -it works fine. The issue I'm having is since I'm using fan out I generate the .childByAutoIdkey before the data is sent. The user presses a send button to start the process but it's always the same exact .childByAutoId key so I'm just overwriting the previous message data. If the user pops the vc and comes back to it then a new key is created but obviously that's terrible ux for a messaging system?
How can I generate different .childByAutoId keys every time the user presses send to fan out?
#obj func sendMessageButtonPressed() {
// ***here's the problem, every time they press send, it's the same exact childByAutoId().key so I'm just overwriting the previous data at the messages/messageId path
guard let messageId = FirebaseManager.Database.database().reference().child("messages")?.childByAutoId().key else { return }
var messageIdDict: [String: Any] = [messageId: "1"]
var messageDict = [String: Any]() // has the fromId, toId, message, and timeStamp on it
let messageIdPath = "messages/\(messageId)"
let fromIdPath = "user-messages/\(currentUserId)"
let toIdPath = "user-messages/\(toId)"
var fanOutDict = [String: Any]()
fanOutDict.updateValue(messageDict, forKey: messageIdPath)
fanOutDict.updateValue(messageIdDict, forKey: fromIdPath)
fanOutDict.updateValue(messageIdDict, forKey: toIdPath)
let rootRef = Database.database().reference()
rootRef?.updateChildValues(fanOutDict)
}
The problem wasn't a new key was not getting generated. #FrankvanPuffelen pointed out in th comments that a new key should get generated every time which is exactly what was happening.
The problem was the fanout was overwriting what was originally written at these 2 paths:
let fromIdPath = "user-messages/\(currentUserId)"
let toIdPath = "user-messages/\(toId)"
It appeared the key was the same because the data kept getting overwritten.
The way I was generating the key works fine

how to observe property changes of Backendless database ? - Swift

I have this code in Swift 3 to get backendless user so I can get his/her properties:
let whereClause = "objectId = '\(userId)'"
let query = BackendlessDataQuery()
query.whereClause = whereClause
let data = Backendless.sharedInstance().persistenceService.of(BackendlessUser.ofClass())
data?.find(query, response: { (result) in
let user = result?.data.first as! BackendlessUser
myLabel.text = user.getProperty("firstName") as! String
})
The code is working fine but my question is how to observe the property changes ? is there a way if the value of property firstName changed I can update my label automatically ?
The use-case you describe is not really as simple as it may seem, but it's definitely possible.
You can capture any changes in Users table by creating an afterUpdate event handler. From there you could publish a message to some dedicated channel in messaging service.
At the same time, your application should be subscribed to this same channel. This way you could update your UI when the appropriate message is received.

iOS Swift: retrieve an entry from the database for the user currently logged in

How do I retrieve a value (other than username and user id, which seem easier to get) for the current user from the database.
Ironically, I can set the value as follows and that works just fine:
let databaseRef = FIRDatabase.database().reference()
userID = (FIRAuth.auth()?.currentUser?.uid)! as String
databaseRef.child("users").child(userID!).child("TermCond").setValue("Yes")
But for the life of me I cannot work out what to put instead of setValue if I simply want to retrieve the current TermCond value. I thought just using value as for example in
let DesiredValue = databaseRef.child("users").child(userID!).child("TermCond").value as? String
Would suffice, but nothing works. I am confused why retrieving the value should be more difficult than setting it.
To "read" a value from Firebase, you need to add a reference listener that gets called every time that value changes.
In your case, that could be something like:
let databaseRef = FIRDatabase.database().reference()
databaseRef.child("users").child(userID!).child("TermCond").observe(FIRDataEventType.value, with: { (snapshot) in
let desiredValue = snapshot.value as? String
})
This block of code will get triggered every time your value changes. If you only want to read it once, you can use observeSingleEvent:of:with instead of observe:with.
This is as described in the Firebase documentation: https://firebase.google.com/docs/database/ios/read-and-write
I recommend you read their entire Documentation to get an idea of how Firebase works, as it is very different from traditional databases.
I can also recommend the following tutorial if you'd like to learn a bit more about the Firebase Database and how it works: https://www.raywenderlich.com/139322/firebase-tutorial-getting-started-2
I've solved this now (based on Aleksander's reply). The way I did it is as follows.
databaseRef.child("users").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
let value = snapshot.value as? NSDictionary
self.desiredValue = value?["TermCond"] as? String ?? ""
self.LabelToShow.text = self.desiredValue!
}) { (error) in
print(error.localizedDescription)
}
This works absolutely fine and shows the value of TermCond in the LabelToShow on my iOS screen.

Problems with structuring and retrieving data from Firebase in Swift

I am designing a litte quiz app but I'm having trouble while retrieving the game data.
As you can see in the picture I have an JSON object that contains many single games. Each single game has a unique id. My first problem is that each of the games can be available in multiple languages. I know that I could download the hole snap and then looping throw each game but that would mean really long loading times while the app is growing.
In short form:
I need to retrieve the following data from the JSON above:
A random game wich is available in a specific language (need to have the key en for example)
All games that are available in "en" but not yet in "de"
If it is easier to restructure the data in the JSON, please tell me.
Thanks for helping me.
Answer to your first part :-
let enRef = FIRDatabase.database().reference().child("singleGames").child(singleGamesUID).child("en")
enRef.observeEventType(.Value, withBlock: {(snap) in
if let enQuizQuestion = snap.value as? [String:AnyObject]{
//Question exists : Retrieve Data
}else{
//Question in english doesn't exist
}
})
For your second part
Since you are trying to save iteration time might i suggest you also save your singleGames id in a separate languagesBased nodes, there is a command in firebase that allows you to search for some keyValues in your child node's , but even that i think would be executing a search algorithm which might be a little more time consuming :--
appServerName:{
singleGames :{
uid1:{......
......
...},
uid2:{......
......
...},
uid3:{......
......
...}
},
enQuestions:{
uid3 : true
}
deQuestions:{
uid1 : true,
uid2 : true
}
}
Now all you gotta do :-
let rootRef = FIRDatabase.database().reference().child("deQuestions").observeEventType(.Value, withBlock: {(qSnap) in
if let qDict = qSnap.value as? [String:AnyObject]{
for each in qDict as [String:AnyObject]{
let deUID = each.0
}
}else{
//No question in dutch language
}
})

Resources