cloudkit enter userID as reference of a new record (in code) - swift

I am setting an app in which a user could create records. Let's say he/she is the owner of a chatroom. Therefore there is an attribute called "admin" in the chatroom record. This attribute takes a reference which is the ID of the owner.
Here is what I tried:
CKContainer.defaultContainer().fetchUserRecordIDWithCompletionHandler({
userRecordID, error in
if error != nil {
println("caca")
} else {
println("gettin close")
let UserRecordIDToStore = NSKeyedArchiver.archivedDataWithRootObject(userRecordID)
let iDString = userRecordID.recordName as String
daMainUser.setObject(iDString, forKey: "user")
}
})
When I pass iDString as above, and I create the record (the room), its admin reference is empty. Whether I did cast iDString as a String or not.
When I pass userRecordID directly, I get an error:
'CKRecordID' is not identical to 'CKRecordValue'
I have been looking everywhere but I cannot find more information about this.
Any help would be greatly appreciated. Thank you guys!

If your user field is set up as a CKReference field, then you should set it like this:
daMainUser.setObject(CKReference(recordID: userRecordID, action: CKReferenceAction.None), forKey: "user")
In your case you do not have to create a recordID because you already have it. Otherwise you had to create it with something like:
var recordID = CKRecordID(recordName: userRecordID.recordName)

Related

Swift saving new comments using CloudKit

I'm trying to make an app which stores a user's comment on CloudKit and then shows it to the other users. User simply enters his/her comment on a text field and clicks on a submit button to submit his/her comment (just like a restaurant app). However, I can't seem to find the correct way no matter what I try. Here is my code, I'd be very glad for any help as I've been stuck on this problem for some time now. Thank you very much in advance!
#IBAction func OnSubmitTouched(_ sender: UIButton) {
if (textField.text != ""){
let newComment = CKRecord(recordType: "Users")
let publicDB = CKContainer.default().publicCloudDatabase
newComment.setValue(textField.text!, forKey: "comment")
publicDB.save(newComment){
rec ,err in
if let error = err {
print(err.debugDescription)
return
}
publicDB.fetch(withRecordID: newComment.recordID){
rec, err in
print(rec!["comment"]!)
return
}
}
let predicate = NSPredicate(value: true)
let query = CKQuery(recordType: "comment", predicate: predicate)
let operation = CKQueryOperation(query: query)
var commentRecords: [CKRecord] = []
operation.recordFetchedBlock = { record in
commentRecords.append(record)
}
operation.queryCompletionBlock = { cursor, error in
print(commentRecords)
}
CKContainer.default().publicCloudDatabase.add(operation)
}
}
You are getting a permission error because Users is a protected record type that CloudKit creates automatically for users of your app. You should name it something else and then it should work.
For example, you could make a Comment record type. This might need a field that references the current user. You can get the current userID with:
CKContainer fetchUserRecordIDWithCompletionHandler:
Here is the Apple documentation for this method.
It is also possible to use the Users record type, but you would have to find the existing userID from CloudKit as above then build a record around that.
See also this answer.

When retrieving data from Firebase Database, <null> is returned: "Snap (...) <null>"

I'm a relatively new Swift programmer and am using Firebase for the first time so please excuse any misunderstandings I may have and my lack of knowledge about terminology.
I am attempting to retrieve data about a user that is stored in a database (email and username).
The code successfully finds the userID in the database. The userID is then used in order to navigate into the directory containing the username and email. It stores those values in snapshot.
For some reason, when snapshot is printed, it shows the userID but the contents of the directory (username and password) are shown as <null>. I am certain that the directory I am attempting to access and retrieve data from exists and is not empty (it contains a username and email). I wantsnapshot to store the username and email, but printing shows that it is not doing so correctly and I cannot figure out why.
here is my code block:
func checkIfUserIsLoggedIn() {
if Auth.auth().currentUser?.uid == nil {
perform(#selector(handleLogout), with: nil, afterDelay: 0)
} else {
let uid = Auth.auth().currentUser?.uid;
Database.database().reference().child("Users").child(uid!).observeSingleEvent(of: .value, with: { (snapshot) in
print(snapshot)
if let dictionary = snapshot.value as?[String:AnyObject] {
self.userLabel.text = dictionary["name"] as? String
}
}, withCancel: nil)
}
}
and here is what is being printed to the console:
Snap (ywU56lTAUhRpl3csQGI8W8WmQRf1) <null>
Here is the database entry I am attempting to reach and log to snapshot:
I'm a new Stack Overflow user and don't have enough experience on the site to be allowed to embed images in posts, so this is the external link
Thanks for reading, any help would be much appreciated!!
Your reference in Firebase is to "users", but you are using .child("Users") in your code. Make sure your lookup matches case to your node. I find it best to create a reference to that node and use it for writing to and reading from.
let usersRef = Database.Database().reference().child("users")
Snap (ywU56lTAUhRpl3csQGI8W8WmQRf1) <null> the portion in parenthesis refers to the end node of what you are trying to observe. In this case it refers to uid!.
if u want to get username or email then you make first the model class for
Example:-
class User: NSObject {
var name: String?
var email: String?
}
then user firebase methed observeSingleEvent
FIRDatabase.database().reference().child("user").child(uid).observeSingleEvent(of: .value, with: { (snapShot) in
if let dictionary = snapShot.value as? [String: Any]{
// self.navigationItem.title = dictionary["name"] as? String
let user = User()
user.setValuesForKeys(dictionary)
self.setUpNavigationBarWithUser(user: user)
}
})`
if it is not finding your asking values, you are asking wrong directory. check firebase db child name it must be exactly like in your code ("Users")

How can I access value from pointer inside pointer on query with Parse in swift?

How can I access value from pointer inside pointer on query with Parse in swift?
This has to do with three classes in Parse. One is called Post_Story, on is Post and one is User. When I query for Post_Story i am able to retreive pointer info from a key "Post", but is there any way to access information from a pointer within that pointer? (key "createdBy" to User class)
My code looks like this:
let postQuery = PFQuery(className: "Post_Story")
postQuery.whereKey("story", containedIn: storyObjects)
postQuery.includeKey("post")
postQuery.findObjectsInBackgroundWithBlock { (objects:[PFObject]?, error:NSError?) in
if error == nil {
for object in objects! {
if let postL = object["post"] as? PFObject {
if postL["createdBy"] != nil {
//this is where I want to get infor from PFUser, but not all info is sent
print((postL["createdBy"] as! PFUser)) //prints PFUser object without username etc.
}
}
}
}
else {}
}
I hope the question is not too stupid...
You can add postQuery.includeKey("post.createdBy") to include the user object in the createdBy column of post.

Retrieving Data from FireBase SWIFT

I'm trying to get data out of a firebase database if the addedByUser = a value stored in the application.
With what I currently have, nothing is appearing in the table.
The firebase database looks like this:
workout1
"name"
"addedByUser"
My code looks like this:
workout3Ref.observeEventType(.Value, withBlock: { snapshot in
var newWorkout = [Workout1Info]()
for item in snapshot.children {
let createdBy = snapshot.value["addedByUser"] as? String
if createdBy == Username.sharedInstance.userDetail {
let workoutItem = Workout1Info(snapshot: item as! FDataSnapshot)
newWorkout.append(workoutItem)
}
}
self.workouts = newWorkout
self.tableView.reloadData()
})
When I get data normally without comparing if the addedByUser it normally works. Does anyone know why it isn't working?
Thanks for the help
Here's my guess based on a super vague question with some coding issues:
The createdBy is the users name or uid as a string.
The Username.sharedInstance.userDetail is an object (of some kind)
So you are comparing a String to an object that isn't a string, and that won't work.
Also, if the node you are query-ing is the /workout1 node, then you should probably name your reference workout1Ref instead of workout3Ref. That may help keep things straight in code.
While you are comaparing String createdBy with Username.sharedInstance.userDetail check your property Username.sharedInstance.userDetail also should be of String type.

How to access custom user table columns from Parse.com

How should I access columns that I've added to the User table when I have a currentUser object?
I have a PFUser.currentUser() and I want to access the nickname column that I added via the web interface.
Can I use the currentUser to get the data e.g.:
var nickname = PFUser.currentUser()["nickname"] as String
Or do I have to use a user query? e.g.:
var query = PFUser.query()
query.whereKey("username", equalTo:PFUser.currentUser().username)
var user = query.findObjects().first as PFUser
var nickname = user["nickname"]
If you added date to the column locally, then you have to use the first way as you wrote, or if you added date in the browser, or uploaded to parse.com some way, you have to use the second way.
I would like to give my two cents too. First of all, Daniel was right in saying that if you added the date in the browser or uploaded it to parse.com, you need to use the second way. This is an updated answer with iOS 9 and Xcode 7.2:
var query = PFUser.query()
query!.whereKey("username", equalTo:PFUser.currentUser()!.username!)
do {
user = try query!.findObjects().first as! PFUser
} catch {
print("Error finding user")
}
if user?["rankNumber"] as? Int == nil {
user!["rankNumber"] = 0
user!.saveInBackground()
} else {
print(user!["rankNumber"] as! Int)
}
If I did it any other way, xcode would give me an error saying "failing to unwrap optional". I hope this can help someone!