cloudkit: how to access main user's attributes? - swift

I am trying to make an app in which every user would have a personal avatar, a nickname and so on.
I don't know how to access the user's account on cloudkit.
My solution would be to retrieve user's AppleID, query Cloudkit and modify the user's attribute... But I guess there should be a better way to do it. Isn't their something like NSUserDefault but for cloudkit?

You first have to find out what the current loged in userId is. You can do that by executing the fetchUserRecordIDWithCompletionHandler method on the container. Then you can get more (currently only first and last name) information by executing the discoverUserInfoWithUserRecordID on that container.
You could extend the Users table with extra custom fields, but I would not advice doing that. The Users table is a special system table with some limitations. It would be better to create a separate recordType with the user settings. Just add a CKReference to the users table for easy access.
You also have to be aware that a user could log out and log in with a different iCloud account during the operation of your app. You could capture this by executing the code below right after your application start. Of course you have to implement your own logic where you see the NSLog
var ubiquityIdentityDidChangeNotificationToken = NSNotificationCenter.defaultCenter().addObserverForName(NSUbiquityIdentityDidChangeNotification, object: nil, queue: nil) { _ in
NSLog("The user’s iCloud login changed: should refresh all user data.")
}

Related

How to add new field to current logged in user (Meteor.user())?

I am trying to use PeerJS library to implement audio calling. I want the user to be able to call specific user based on his peerId. The only way I could come up with is to store the current logged in peerId in his document in the database.
My question is, how can I add new field to the Meteor.user() document?
The user database is accessible via Meteor.users as specified in the docs. Further reading in the guide explains that any field can be added to a user document, so you could just set up your own object at root document level to store peer connection info. The accounts package is set up so that the profile field of the user document can be updated from the client by the logged-in user, unless a deny access rule has been set up. So, you could do what you're asking with something like:
Meteor.users.update(Meteor.userId(), { $set: { 'profile.peerId': desiredPeerId } })

How to atomically delete user and user's data from Firebase Auth and Realtime Database respectively?

Some background
When a user account is created, I do 3 things using callback chaining in the sequence 1 > 2 > 3.
A user is created in Firebase Auth (the standard way using createUser(withEmail ...))
I upload the user's profile picture to Firebase Storage and capture the returned downloadUrl for use in step 3
I store the user's other information (including the downloadUrl from step 2) in a node in the realtime database (keyed by $userid)
Now the problem
I provide a button called 'Delete account' which should enable the user to delete everything. That is, clear all their data in the Realtime Database, clear their profile picture in Firebase Storage, and finally delete their account from Auth. The important thing is that all these operations should succeed or be canceled if even one fails.
I've gone through ~10 pages of S/O questions & answers, there was 1 unanswered question like this one (it asked about the account creation process...I suppose an answer to that question can easily be adapted here.)
What have i tried?
Currently, I use callback chaining like so:
// start by atomically deleting all the user data from the Realtime Database using the fanout system.
- get all appropriate locations and save in fanout dictionary
- update all these locations to nil // atomic goodness :)
-callback:
-on failure:
- just return // no worries, nothing has changed yet :/
-on success:
// proceed to delete user files on firebase storage
- delete path $userid on firebase storage
-callback:
-on failure: // this is bad, no idea what to do :(
-on success:
// proceed to delete account from Auth
- delete user account from Auth
-callback:
-on failure: // this is terrible, also, it could happen often b/c firebase does ask for re-authentication sometimes :(
-on success: // thank goodness! I have an authListener somewhere ready to show the 'signInViewController' :)
How do you handle such multi-system (Auth, Storage, RealtimeDB) operation atomically? I have looked into transactions but can't see how they can be adapted for this - the docs only show them being used in incrementing counters for likes/stars etc in the RealtimeDB.
Any help will be very much appreciated.
So the main problem is what to do if the data you're trying to delete is being deleted only partially.
I think you should think about a method that will help you restore it if something goes wrong.
I'm not on my computer now but I suggest you to try to download the data that you want to delete and only if there were a success you delete the local copy too, otherwise you should be able to restore it easily.
Edit: if we talk about a serious amount of storage instead of a local copy you can make it on the cloud.
So you first copy this data, then delete it, then delete the database data (also copied previously) then you can delete the user account and finally you can delete the copy.

Request Tracker for Users created without privileges

I have configured request tracker4 to be an interdepartmental helpdesk solution. The current setup is that users will login to RT using LDAP. Once logged in there account is automatically created. However, their account is created with no privileges.
To fix this I have been having to go to Tools-->Configuration-->Select then put in the users DN name and clicking add I then have to check the box "Let this user be granted rights (Privileged)" I have also tried setting Set($AutoCreate, Privileged); but no luck.
I looked at the user accounts in the sqlite database and noticed that when new user logs in they are indeed created in the database. But with no privileges.
709|tuser3|*NO-PASSWORD*|||||||tuser3|||||||tuser3||tuser3|||||||||||||1|2013-03-08 13:47:38|1|2013-03-08 13:47:38
791|Mayra|*NO-PASSWORD*||||Mayra#**************||Main Office|Mayra Hernandez|||||||Mayra||Mayra||**************|||||||||||1|2013-04-03 21:46:36|1|2013-04-03 21:46:36
797|sdrakeford|*NO-PASSWORD*||Autocreated when added as a watcher||sdrakeford#**************|||Sophia C. Drakeford|||||||sdrakeford||sdrakeford|||||||||||||1|2013-04-04 13:18:58|1|2013-04-04 13:18:58
827|Robert.Troy|*NO-PASSWORD*||||Robert.Troy#*******************||Main Office|Robert Troy|||||||Robert.Troy||Robert.Troy||***************|||||||||||1|2013-04-04 16:11:58|1|2013-04-04 16:11:59
Am I missing something, because usually these things are quite obvious.
The $AutoCreate option takes a hashref with all of the default options you want to pass to the User Create method. Try something like:
Set($AutoCreate, {
Privileged => 1
});
(As an aside, it's generally not recommended to run a production instance on sqlite. You might want to consider converting to MySQL or Postgres.)

API call to retrieve all public information of Facebook user?

I know I can call each individual field via something like
/---ID----?fields=gender,languages,age_range,bio,birthday,education,email,hometown
Is there a quicker way than listing every single field?
It is ok if the user has most of these fields locked down with their privacy settings, I just want it to pull what is available.
just try:
https://graph.facebook.com/{{ username or uid }}?access_token={{access token goes here}}
Example:
https://graph.facebook.com/zuck?access_token=###
will give all the public information available for that user.

XCode: how to get the email of the user programmatically?

I would like to avoid to ask my user to fill in a field with his email (long and discouraging). Is there a way to get the email of the user in order to avoid that he has to write it ?
Thanks !!!
Ask first time, make user select remember me option through UISwitch, save it inside a plist (ENCRYPT and then SAVE IT). Next time read the plist. If user like to write every time then good for them, else they can user your given option to save it and then later you can complete the field automatically!
If you mean the apple ID email, then you cannot access it, you will have to ask the email explicitly