Retrieve username from Parse - ios

I've been trying to retrieve the username for a certain user from a user object in Parse. One of the queries i tried to to that with looks like this:
let query = PFQuery(className: "User")
query.whereKey("objectId", equalTo: userId!)
query.findObjectsInBackgroundWithBlock{(objects:[PFObject]?, error: NSError?) -> Void in
if error == nil {
for object in objects! {
self.username.text = String(object["username"])
}
}
}
Is there another way to do this? I'm really new to working with Parse and I really haven't found a way to make this work yet..

When querying the user table, use PFUser.query() to construct your query rather than PFQuery(className: "User")
let query = PFUser.query()
query.whereKey("objectId",equalTo: userId!)
query.findFirstObjectInBackgroundWithBlock{(object,error)->Void in
if error == nil{
if let user = object as? PFUser{
self.username.text = user.username;
}
}
}

Related

the query findObjectsInBackground not working

i have 3 classes, i need to retrieve data depending on some condition , i use this code :
let query = PFQuery(className: "RiderRequest")
query.whereKey("username", equalTo: (PFUser.current()?.username!)!)
query.findObjectsInBackground(block: { (objects, error) in
if let riderRequests = objects {
for riderRequest in riderRequests {
if let driverUsername = riderRequest["driverResponded"] {
let query3 = PFQuery(className: "User")
query3.whereKey("username", equalTo: driverUsername)
query3.findObjectsInBackground(block: { (objects, error) in
if let driverinfo = objects {
for driver in driverinfo {
print("driverobject=\(driver)")
}
}
})
but the className: "User" not working and cant get data from it , always the object is nil.
Another way to retrieve data from the User Class with PFQuery is using the following:
let query : PFQuery = PFQuery(className: "_User")
Parse User is a special Parse class and requires a different Query constructor.
Update your code to:
let query3 = PFUser.query()

Querying from Parse Classes

I am trying to query the user's from _User class, which I have managed successfully. But what I am trying to do now where I'm having a bit of difficulty, is query another class, Posts, and download the images that match the users downloaded from the first query?!
So I am just trying to assign the images from the Posts class to the correct users from the _User class...It sounds very simple, but it driving me mad!!
Here's my code for the query, I know it's probably not the best way but I'm newish to Swift! But I'm willing to try any tips or recommendations if you have any!
let userQuery = PFQuery(className: "_User")
userQuery.addDescendingOrder("createdAt")
userQuery.findObjectsInBackgroundWithBlock ({
(objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
self.profilePicArray.removeAll(keepCapacity: false)
self.usernameArray.removeAll(keepCapacity: false)
self.fullnameArray.removeAll(keepCapacity: false)
self.uuidArray.removeAll(keepCapacity: false)
for an object in objects! {
self.profilePicArray.append(object.valueForKey("profilePicture") as! PFFile)
self.usernameArray.append(object.valueForKey("username") as! String)
self.fullnameArray.append(object.valueForKey("firstname") as! String)
self.uuidArray.append(object.valueForKey("uuid") as! String)
}
let imageQuery = PFQuery(className: "Posts")
imageQuery.whereKey("username", containedIn: self.usernameArray)
imageQuery.findObjectsInBackgroundWithBlock({ (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
self.lastPicArray.removeAll(keepCapacity: false)
for an object in objects! {
self.lastPicArray.append(object.valueForKey("image") as! PFFile)
}
self.collectionView.reloadData()
} else {
print(error!.localizedDescription)
}
})
} else {
print(error!.localizedDescription)
}
})
The result I am getting at the moment is that: all user's download and also all the posts, but the images are just assigned randomly to each user or all the posts appear for each single user!
Thanks in advance.
New Query
func uu() {
let query = PFQuery(className: "_User")
query.addDescendingOrder("createdAt")
query.includeKey("latestImage")
query.whereKey("username", notEqualTo: PFUser.currentUser()!.username!)
query.findObjectsInBackgroundWithBlock { (object:[PFObject]?, error:NSError?) -> Void in
if error == nil {
for object in object! {
if (object.objectForKey("latestImage") != nil)
{
self.lastPicArray.append(object.objectForKey("latestImage")!.valueForKey("image") as! PFFile)
self.profilePicArray.append(object.valueForKey("profilePicture") as! PFFile)
self.fullnameArray.append(object.valueForKey("firstname") as! String)
self.usernameArr.append(object.valueForKey("username") as! String)
}
}
self.collectionView.reloadData()
print(self.usernameArr)
print(self.lastPicArray)
}
}
}
You should be able to do this with just one query, by using the includeKey function of Parse Queries
Parse Queries
Take your 2nd query, and add something like this:
let imageQuery = PFQuery(className: "Posts")
imageQuery.whereKey("username", containedIn: self.usernameArray)
imageQuery.includeKey("fieldNameOfUserPointer")
Just change the 'fieldNameOfUserPointer' to the field name that references your _User object in the Posts entity.

Parse query containedIn doesn't return any value

Several days I'm trying to crack why my code doesn't work and everything I've tried doesn't give me any result. Heres the deal:
There is a Booking class that contains userFrom who made booking
let query = PFQuery(className: "Booking")
query.whereKey("offer", equalTo: offer.pfObject!)
if self.typeOfUser == .COOK { //! If user is a Cook
query.findObjectsInBackgroundWithBlock({ (objects : [PFObject]?, error : NSError?) -> Void in
if let error = error {
print(error.localizedDescription)
} else {
if let objects = objects {
self.bookings = objects
self.usersIds = [String]()
for object in objects {
let userFrom = object.objectForKey("userFrom") as? PFObject
let userId = userFrom!.objectId! as String
self.usersIds.append(userId)
}
self.getUserInfoForBooking()
} else {
print("Something went wrong")
}
}
})
}
From every user I get objectId and append it to the [String] array. Then I query users with their IDs
private func getUserInfoForBooking() {
let userQuery = PFQuery(className: "User")
userQuery.whereKey("objectId", containedIn: self.usersIds)
userQuery.findObjectsInBackgroundWithBlock({ (objects : [PFObject]?, error : NSError?) -> Void in
if let error = error {
print(error.localizedDescription)
} else {
print(objects!)
if let objects = objects {
for object in objects {
self.users.append(object)
}
self.collectionView.reloadData()
}
}
})
}
In this query I always get an empty array.
Whatever I did, whatever I've changed always [] in response :(
This is the wrong way to query users
let userQuery = PFQuery(className: "User")
Because the class name is private. You should be creating the query as
let userQuery = PFUser.query()

Issues with changing existing Parse data

I am working with Parse for the first time in my application, and everything seems to be working well with the exception of when I go to change existing data. I am simply trying to change a string value that I have stored in a column of one of my items.
This is the code I currently have:
func sendTimeToParse() {
var query = PFQuery(className: "ClassName")
query.whereKey("Name", equalTo: rideNamePassed)
query.getFirstObjectInBackgroundWithBlock {
(object: PFObject?, error: NSError?) -> Void in
if error != nil {
println("The getFirstObject request failed.")
} else {
// The find succeeded.
let object = PFObject(className: "ClassName")
object.setValue(self.timeSelected, forKey: "WaitTime")
object.saveInBackground()
println("Successfully retrieved the object.")
}
}
}
}
At the moment it just seems to create a new row of data and saves the time to that, however obviously I would like it to change the existing data in whatever row matches the name of the current record.
Anyone have any suggestions?
The problem is that you are creating a new PFObject with the line let object = PFObject(className: "ClassName") instead of using the retrieved object which is given as a parameter.
Simply delete the line let object = PFObject(className: "ClassName") and unwrap the received optional. It could look something like the following:
func sendTimeToParse() {
var query = PFQuery(className: "ClassName")
query.whereKey("Name", equalTo: rideNamePassed)
query.getFirstObjectInBackgroundWithBlock {
(object: PFObject?, error: NSError?) -> Void in
if error != nil {
println("The getFirstObject request failed.")
} else {
if let obj = object {
obj.setValue(self.timeSelected, forKey: "WaitTime")
obj.saveInBackground()
}
println("Successfully retrieved the object.")
}
}
}

Get all values in a field

I'm using Parse
I have a "Post" class with fields.
Post class have some field, and one of it is "user" linked with "User" class
I want query Post class and get all the users in the response.
let query = PFQuery(className: "Post")
// How to get all user in the post class
Is there another way like..
let query = PFQuery(className: "Post")
let usersQuery = PFUser.query()
usersQuery.whereKey("SELF", matchesKey: "user", inQuery: query)
But I know there is no SELF keyword
Objective C is also fine
Given this page in the Parse documentation, it should look something like this:
let query = PFQuery(className: "Post")
query.findObjectsInBackground() { posts, error in
if (!error) {
for post in posts {
let user = post["user"]
println("User: \(user)")
}
} else {
// Log details of the failure
println("Error: \(error), \(error.userInfo)")
}
}
In Parse you use a PFQuery to query the database..
In a callback (asynchronusly) you get a PFObject or an array of PFObjects.
How to do this is written in their guide
Here's a little example:
You can get all properties/fields whatever by calling the array function on the PFObject.
var pfObject = PFObject()
pfObject["yourcolumn"] as? String //Whatever you want
In your case a PFUser would be the solution
pfObject["yourusercolumn"] as? PFUser
To query you use a PFQuery
Asynchronusly (preffered):
var query = PFQuery(className:"GameScore")
query.whereKey("playerName", equalTo:"Sean Plott")
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
// The find succeeded.
println("Successfully retrieved \(objects!.count) scores.")
// Do something with the found objects
if let objects = objects as? [PFObject] {
for object in objects {
println(object.objectId)
}
}
} else {
// Log details of the failure
println("Error: \(error!) \(error!.userInfo!)")
}
}
Synchronusly:
var query = PFQuery(className:"GameScore")
var objects = query.findObjects()
for object in objects {
// Do whatever you want with your pfobject
}
Asynchronus queries are more likely because they don't run on the GUI thread what makes your app way more faster (on the UI).

Resources