Invite to CKShare and Accept CKShare without UICloudSharingController and without sending link with URL - cloudkit

Say I am making Root <-> Child application (i.e. Manager <-> Employee).
Say Manager has predefined email and already granted userDiscoverability application permission (via CKContainer.requestApplicationPermission).
When Employee starts application, initialisation sequence automatically creates CKRecord (i.e. Employee record for time tracking), CKShare and silently invites Manager to CKShare.
For achieving this I am using CKContainer.discoverUserIdentity, then CKContainer.fetchShareParticipant, then CKModifyRecordsOperation which saves both CKRecord and CKShare.
After initialisation flow in private database of Employee I have record type of cloudkit.share which has 2 participants, Employee itself and Manager. Acceptance status of Manager is INVITED. Also I have URL link which I got after saving CKShare.
Now on Manager side I want silently accept CKShare invitation in order to access Employee record (i.e. for time tracking).
How to silently accept CKShare invitation without need of sending URL link via email, Messages.app, without using UICloudSharingController, etc.?
Is it possible to purely programmatically, silently, using CloudKit only share CKShare from one side and accept it on other side?
Thank you!

Related

How do I trigger a blocking function when a new user registers to check that their email address is in a collection?

I have a flutter app using firebase and google cloud. The organization providing the app to their users uploads a list of users that are able to register and create an account. When a user goes to register I want two things to happen:
They are given an error message if their email address and ID number do not match an existing document with email and ID field values
Existing fields, like their department and deck number that are in the collection uploaded by the organization are copied to their new user profile
I would write a cloud v2 function. The documentation has some great examples of how to block registration. What you would want to do is in the beforeUserCreated method, look up the field in firestore to validate that their email. You can get their email through the AuthBlockingEventType additionalUserInfo field which should provide the username (email in this case) to compare against the firestore database.
Deploying an AuthBlocking function is the same deployment as any other function.
Once deployed, you will need to remember to register your blocking function for it to take effect.
As far as updating their user profile information, you could just use another cloud function to listen for a database change once the user is registered and then copy that data over.

Is there a way to automatically assign a User an ID in Firebase? IOS

I am new to Firebase and I have been working within IOS to identify the users by an automatically generated key. Essentially I'm creating a leaderboard with highscores and levels. Instead of having the user sign up for an account I want them to already have an ID so they can just start playing and write their high scores to the leader board. At the moment I have this code:
let user = Auth.auth().currentUser
ref?.child("Highscore").child((user?.uid)!).setValue(highscoreArray)
For some reason I'm getting an error that the "user" is non-existant. Is there a way to automatically generate one without having to force the user to choose a username etc. Also I've tried childByAutoID and i keep getting new IDs within the simulator everytime I run it.
Thanks for the help.
Minimally, you have to put the user through a sign-in process. Auth.auth().currentUser won't return anything but null until that process is complete. There is no workaround for this requirement. The only way you get a uid is after the user signs in a creates an account.
If you don't want to user to have to do anything to sign in, you can enable and implement anonymous authentication to sign them in without requiring any input from them. You can then upgrade their account later in order to make it permanent, since anonymous accounts don't transfer between devices or survive an app uninstall.

How to linking a users data to his future account at the time of signup in Stitch

I would like to use Stitch to sign up users. Each user must have a unqiue email and a unique user-name.
This is important for applications like chats or forums, where users should not be forced to reveal their email when communicating.
I already implemented login with email and password as described here: https://docs.mongodb.com/stitch/authentication/userpass/#authenticate-a-user
The problem is:
How to securely save a user-name on signup? I could store a users desired name in a collection and merge it into his custom user data after initial login. In order to do that, I would need to grant the user write privileges to whichever collection holds pending names. This is unsafe, since he could now change the name after the fact or even change other peoples names while they are pending.
The user needs to choose his name at the time of signup. At this time the user is still logged in via anonymous credentials. Hence, I can not restrict users to changing only their own data since they are at this point sill anonymous. I see no way of linking a users data to his future account at the time of signup. Any idea to change that?
It would seem strange, if stitch lacked the functionalities to easily sign up users with a unique name/handle in addition to email address.
I haven't used your exact software but in general I would approach the problem as follows:
When someone starts using the application anonymously, create a user object. The user at this point does not have a reserved (i.e. globally unique) user name, or email address, etc. But the user still has an internal identifier.
Associate user-visible state with the user object. This could be done through server-side sessions or signed cookies. (Unlike unsigned cookies, cryptographically signed cookies permit server to store what would otherwise have to be stored in the server-side session in a cookie, and trust that the client hasn't tampered with the information by e.g. changing the user id).
When user registers, set the user name, email address, etc. on the existing user object. User id remains the same and allows the user to continue to have access to their anonymously-generated data.
Have a process for deleting anonymous users that don't register after some time.

"Unsubscribe" From CKQuerySubscription Without Removing It (Multiple Users)

I have a Role Type that multiple users are subscribed to recordCreation changes for.
It's easy to add new users to this CKQuerySubscription by using its subscriptionID, however the issue arises when I try to 'unsubscribe' one of the users from the subscription using the CKContainer.default().publicCloudDatabase.delete(withSubscriptionID:) method.
Rather than just stopping this device from receiving any further notifications, it deletes the subscription (for all other users as well).
So my question is: how do I remove one user from a CKQuerySubscription without deleting the subscription for other users who are also subscribed to it?

Friend list through relations

I'm creating a social media app. I'm able to allow the current user to search for a PFUser and add the user to a friendship relation. I'm struggling on accessing the friendship relation and getting all the friends to create a table view right now. Could someone help me with this?
A Relation type in Parse represents just like what it literal meaning is. It's just a relation that contains no data. If you want to access the data inside the relation. You will need to perform query on it like so:
let query = relation.query() // I assume relation is an instance of PFRelation you want
Actually, Parse tutorial provides us a very comprehensive guide and you should check that first: https://parse.com/docs/ios/guide#relations
NOTE: This answer provides alternatives to using Relations to make a Friend System
I have created a friend system in two ways using Parse and both a function of your specific needs.
The first time I implemented a friend system. I had a table of Users and a table of Relationships. The Relationships table stored the usernames (or ObjectIds) of the two users in a relationship and the state of that relationship (friends, request sent, etc). The problem with this is that the queries can be kinda complicated, and if you have a lot of users, this may end up being too slow.
The second option is storing friend information in the User table itself. For each user, you add the columns with they type Array: Friends, RequestSent, and RequestReceived. Anytime a user sends a request they update their own user row and send a message to CloudCode to update the other affected user. Take a look at this example:
User A sends a request to User B:
User A adds user B's name to RequestSent
User A sends a message to cloud code that he/she wants to add user B
CloudCode adds User A's name to User B's RequestReceived
User B wants to accept User A's request
User B adds user A's name to Friends
User B removes user A's name from RequestSent
User B sends a message to CloudCode that he/she wants to accept User A's friend Request
CloudCode adds user A's name to Friends
CloudCode removes user A's name from RequestReceived
With this option, you never perform any server side queries. You only ever perform get operations. The downside to this option is if the logged-in user has thousands of friends/requests, it will take a while to download that information.
Note: The reason you have to use CloudCode is that a User can only change information about him/herself. The other option is to have CloudCode manage all the adding/removing so better checks can be made.
I found with this method that you can sometimes have one user who is listed a a friend in another users row but not their own. Controlling everything from CloudCode could eliminate this kind of error.