CKError when querying system field: rejected "Unknown Field 'createdAt'" - cloudkit

I am sorting the createdAt system field like this:
query.sortDescriptors = [NSSortDescriptor(key: "createdAt", ascending: false)]
and get the following error:
CKError 0x1c4447fb0: "Invalid Arguments" (12/2018); server message =
"Unknown field 'createdAt'"; uuid =
9C450848-2449-4892-93BC-C46363203042; container ID = "...
I am able to query and sort fields that I create in this manner. Anything different with a system field?
The field's index is sortable and queryable.

Use creationDate for the key, instead. The meta keys in the CK dashboard vary slightly from the ones used for queries. Here's a list of meta keys:
recordID: CKRecordID
The unique ID of the record.
recordType: String
The app-defined string that identifies the type of the record.
creationDate: Date?
The time when the record was first saved to the server.
creatorUserRecordID: CKRecordID?
The ID of the user who created the record.
modificationDate: Date?
The time when the record was last saved to the server.
lastModifiedUserRecordID: CKRecordID?
The ID of the user who last modified the record.
recordChangeTag: String?
A string containing the server change token for the record.

Related

GORM unable to update data in one to many relationship

I have two tables users and documents. They are related in such a way that each document must belong to a user using a one to many relationship. When I try updating a document I get the following error
ERROR: insert or update on table "documents" violates foreign key
constraint "fk_users_documents" (SQLSTATE 23503)
Here are my structs definition and update function
type User struct {
gorm.Model
Name string
Email string
Password string
Documents []Document
}
type Document struct {
gorm.Model
Name string
UserID uint
}
//Update document by id
func (h handler)UpdateDocument(w http.ResponseWriter, r *http.Request) {
// once again, we will need to parse the path parameters
var updatedDoc Document
reqBody, _ := ioutil.ReadAll(r.Body)
json.Unmarshal(reqBody, &updatedDoc)
var document Document
vars := mux.Vars(r)
id := vars["id"]
if result := Db.First(&updatedDoc, id); result.Error != nil {
fmt.Println(result.Error)
}
document.Name=updatedDoc.Name
Db.Save(&document)
json.NewEncoder(w).Encode(&updatedDoc)
}
You are calling Db.Save(&document) but document has only its Name field populated. This means that the UserID is set to 0. I'm guessing you don't have any user with ID 0 present in the User table, therefore this violates the foreign key constraint.
The UserID field shall always be set to an existing user when updating a document otherwise the query will fail.
Regardless of this, I'd suggest you to study a bit of database and golang basics because the code you posted is quite messy.

Firestore "updateData" removes all the fields in document

In my prpject I have a "employees" collection where every employee document containes fileds like: firstName, lastName, zipCode, refreshToken etc.
When trying to update just a value of refreshToken i use 'updateData' like shown in documentation docs
my code:
static func updateToken(token:String){
Firestore.firestore().collection("companies").document(self.user.companyId).collection("employees")
.document(self.user.employeeId).updateData(["refreshToken" : token])
}
but that removees all other values of employee document (firstName, lastName, zipCode etc) and just new value of refreshToken exist in the node after operation. Am I doing something worng or I missunderstod idea of "updateData"?
If you want to update the value of a field and if the document does exist, its contents will be overwritten with the newly provided data, unless you specify that the data should be merged into the existing document, as follows:
Firestore.firestore().collection("companies").document(self.user.companyId)
.collection("employees").document(self.user.employeeId)
.setData(["refreshToken" : token], merge: true)
}
See, I have used setData() function instead of updateData().

Mongodb changing the unique key

I have made the users email the unique key for my entire users database:
var usersSchema = new Schema({
_id: String, // Users Unique Email address
name: String, // Users name
phone: String, // Users phone number
country: String, // Country
type: String, // tenant/agent/manager/admin
username: String, // Username for login
password: String, // Password string
trello: Object, // Trello auth settings
settings: Object, // Settings for manager and other things
createDate: Number, // Date user was created
contactDate: Number, // Date user was last contacted
activityDate: Number // Date of last activity on this user (update/log/etc)
});
So what if the user changes email address?
Is my only way to delete the record and create it again?
Or is there a smarter way?
And the users._id (email) have relations in 16 other tables.
Example the booking table
var bookingSchema = new Schema({
_id: String, // Unique booking ID
user: String, // User ID --> users._id
property: String, // Property ID --> property._id
checkin: Number, // Check in Date
checkout: Number // Check out Date
});
One user can have a LOT of bookings
What I would do is find all records that matches the email and then do a for (i=1 ; i<booking.length ; i++) and then update the email of each record
Is there a smarter way to update all emails that matches using only one mongo call?
(the reason is there are so many relations, so my loop seems a bit like a very primitive way of doing it)
I would say it's much cleaner to create a field for email and create an Unique Index on that.
Unfortunately still the relationship as the ones inside the Relational databases isn't supported! There are plans according to the latest talks to create this feature natively.
The best solution for you would be to think how to use the sub-documents to make things more consistent.

Add a record to an Algolia Index only if it does not exists

I was wondering how can i POST in a single request (without fetching results for the given attribute) a pretty simple record to an Algolia Index without creating repeated instances.
e.g:
category: {
name: String // This should be unique
}
There isn't such "addObject if not exists" feature based on the record content but if you use the category name as the objectID of your record; the second time you'll add the object, it will just replace the previous instance.
{
objectID: "mycategoryname",
moreattributes: "if needed",
[...]
}
Would that work?

How to get records with specific IDs?

I can easily get record with specific ID. If I need something specific then I can use CKQueryOperation.
I need to provide it with proper predicate, but I can't specify IDs as parameter of predicate, because it doesn't support CKRecordValue protocol. Another idea is to use CKReference, but how to write proper predicate then?
If I try to use array of Strings and evaluate agains recordID.recordName key path:
var references:[String] = IDs.map{$0.recordName}
var predicate = NSPredicate(format: "ANY recordID.recordName IN %#", references)
I get following error:
<CKError 0x17005f3b0: "Invalid Arguments" (12/1009); "Invalid predicate: recordKey (recordID.recordName) contains invalid characters">
Predicate format output:
predicate ANY recordID.recordName IN {"AFF487BE-4A7E-4F76-8185-79FA2E1EFC33", "D4D83B37-97DE-4BF2-9E43-4C5522E36DF1", "0126008A-0B42-4F95-AB31-BB13B6215475", "6DE83AD9-F307-467D-A5EF-AD2B97B8E7F7", "F701ADBF-9BE7-4F42-8CA9-44D2D0E629F8", "38C4FB60-8A65-43F9-8E1E-4C48D5B60DCD"}
Any help is appreciated.
You can use a CKFetchRecordsOperation to fetch records whose RecordIDs you already know:
let fetchRecordsOperation = CKFetchRecordsOperation(recordIDs: recordIDs)
fetchRecordsOperation.desiredKeys = desiredKeys
Init the operation with an array of the CKRecordIDs you'd like to retrieve and it will return each individual record result in the perRecordCompletionBlock and all records fetched in fetchRecordsCompletionBlock.
You can retrieve the complete records by default or just a subset of their values by setting an array of NSStrings to the desiredKeys property with the names of the fields you'd like to retrieve.