I am using the Installation-Model to allow users to configure which (push) Notifications they want to receive on which device, without having to sign up. Unfortunately, it seems the Installation-Object acts differently than other models. To allow for a smooth setup, I set the channel based on a custom field on first iteration, but then want to allow the user to change them. The parse-code looks like this:
Parse.Cloud.beforeSave(Parse.Installation, async (request) => {
const defaultTeamId = request.object.get("defaultTeamId");
request.object.unset("defaultTeamId");
if (!request.master) {
if (request.user) {
request.object.set("user", request.user);
} else {
request.object.unset("user");
}
}
if (request.original) {
// an update not a create, ignore startingFollows
// but let it return the existing set of channels:
console.log("known");
request.object.set('channels', request.original.get('channels'));
return
}
const channels = []
if (request.user) {
const { teams } = await fetchMyTeams(request.user);
teams.forEach((x) => {
channels.push(x.id)
});
}
if (channels.length === 0 && defaultTeamId) {
channels.push(defaultTeamId);
}
request.object.set("channels", channels.map((x) => `${x}:news`));
});
This generally works as expected, just that the channels are not returned to the user, nor the id of the object when it set/created:
I noticed that there is an empty [] in the protectedFields of the schema:
"protectedFields": {
"*": []
}
Which I canāt change either. Is that related? How can I get the parse-server to return the other fields? Especially since the client doesnāt even get the objectId?
This comes back on the wire/via the network as the response for save - as seen in the browser inspector. I was hoping to see the change of channels, too, but it doesnāt show .
The API only return the fields that were changed so, as peer as my understanding of your code, you should see the channels field being returned when creating a new installation (but not when updating). Do you see a different behavior?
How is that being determined though? Meaning, I donāt have the objectID for the instance for example, and unlike with other models, for Installation none is returned ever, even when creating. If I had that Iād just use it to fetch the entire objects, but afaiu, installation.fetch() doesnāt work for the same reason (doesnāt have an id).
I guess the idea is we return only what has been asked for and been changed on the model during the processing, in the assumption that the other information is known to the sender - but in this case they arenāt.
No, that is what I see (well aside from the oddities around id). But I am wondering whether or how I could make it return other values. Or is it better to just write my own cloud-code function then?
I noticed that the installation rest api refers to a different endpoint /parse/installation rather than the usual /classes/_Installation. Is there any convenient way to send custom parse-post-requests in the JS SDK (other than cloud-code-function-calls)? Then I could also replace this to use that endpoint instead, if thatās whatās neededā¦
I believe thatās not the problem as essentially /installations turn out doing the same thing of /classes/_Installation. I guess it is some problem being generated because of the code. Would you mind to simply create and save a new installation and inspect what you see? For instance, Iāve just tested this curl command:
Just for every following post, doing exactly the same thing, not having any objectId (because in doubt the app was uninstalled, and the only thing available is the same installationId).
(you can see the beforeSave is not enabled as the results donāt show the changes).
If I switch it from _Installation to Installation (so my own class), each entry gets its own objectId, as expected. So there must be something special happening on _Installation I am not aware of. Do you know where that is in the code? Could you point me it and the rational?
iiuc, the following happens: my requests have the same installationId and deviceToken for each request, meaning that on update-requests, the or for installationId would match
which run through all the checks, but as the deviceToken isnāt updated, we just return the objectId (the syntax highlighting is misleading, this is active code)
which is then converted into a regular object-id-based query:
Only because of that, does my beforeSave even get triggered:
Which ends up, tracking the changes made in this beforeSaveand remove the objectId from it - because the object-id was in the query constructed by the installationHandle before (line 281).
Whether intended or not in a bigger picture, not returning the objectId is what is being done at a simple objectId-queried-update - which the _Installation-query is converted into. Doesnāt look like thereās any way around this.