I need some help here.
The APIService generated by codegen has generated this function.
SubscribeToNewMessageListener: Observable<SubscribeToNewMessageSubscription> = API.graphql(
graphqlOperation(
`subscription SubscribeToNewMessage($conversationId: ID!) {
subscribeToNewMessage(conversationId: $conversationId) {
__typename
author {
__typename
cognitoId
id
username
registered
}
content
conversationId
createdAt
id
isSent
recipient {
__typename
cognitoId
id
username
registered
}
sender
}
}`
)
) as Observable<SubscribeToNewMessageSubscription>;
I'm trying to call this listener from an angular page but I can not pass the parameter to the function
always get "Variable 'conversationId' has coerced Null value for NonNull type 'ID!'".
I have tried in all ways but I can not send it.
This is more or less my code.
constructor(
private api: APIService
) {}
ngOnInit() {
this.api.SubscribeToNewMessageListener
.map(msg => msg.conversationId = 'randomGUID')
.subscribe({
next: (x) => {console.log('Next',x)},
error: (e) => {console.log('Error', e)},
complete: () => {}
})
}
Another subscription without parameters, however, it works for me simply by subscribing to it.
Please need help.
Thanks you.
Hey @RidClick,
Can you include the version of aws-amplify you are using?
Actually this seems related to the Amplify CLI codegen. I will pass this back to the CLI repo.
Hey @RidClick,
Can you include the version of aws-amplify you are using?
I am using the latest versions of npm aws
"aws-amplify": "^1.1.22",
"aws-amplify-angular": "^2.1.9"
and global aws-amplify/cli 1.1.7
But I did not think it was an error in the generation of the code, I think my problem is that I do not know how to use it, because I understand how to pass the parameter to an observable, since for it to work, I must pass to the listener the coversationId.
As I said, other listeners without parameters if they work like ...
APIService.ts
SubscribeToNewUsersListener: Observable<SubscribeToNewUsersSubscription> = API.graphql(
graphqlOperation(
`subscription SubscribeToNewUsers {
subscribeToNewUsers {
__typename
id
cognitoId
username
registered
conversations {
userConversations {
conversationId
}
}
}
}`
)
) as Observable<SubscribeToNewUsersSubscription>;
Angular page...
ngOninit() {
this.subscription = this.api.SubscribeToNewUsersListener.subscribe({
next(x) { console.log('next',x) },
error(err) { console.log(`Finished with error: ${ err }`) },
complete() { console.log('Finished') }
});
}
This listener, when I create a new user, returns me in the next statement the new user created,
since the subscription does not receive any parameters.
@RidClick Thank you for reporting this. Codegen doesn't have the support to pass arguments to subscription yet. We will add this to our backlog and get it prioritized.
I am having this exact problem with subscriptions - any updates on this?
I am having this exact problem with subscriptions - any updates on this?
I found a momentary solution that I hope will work for you. You must modify your API.service and try that the subscription functions have more or less this structure.
SubscribeToNewMessageListener(conversationId: string): Observable<SubscribeToNewMessageSubscription> {
const statement = `subscription SubscribeToNewMessage($conversationId: ID!) {
subscribeToNewMessage(conversationId: $conversationId) {
__typename
id
content
isSent
conversationId
createdAt
sender
}
}`;
const gqlAPIServiceArguments: any = {
conversationId
};
return (API.graphql(
graphqlOperation(statement, gqlAPIServiceArguments)
)) as Observable<SubscribeToNewMessageSubscription>;
}
And then on the ngOnInit of your page, you would call it that way, the .map is necessary because if you do not filter the subscription it is called multiple times when you receive a new message,
newMessageId is a global var but can be local, is another filter for the multiple callings.
this.api.SubscribeToNewMessageListener(this.conversationId)
.map((response:any) => {
let message = response.value.data.subscribeToNewMessage;
return message;
})
.subscribe(message => {
console.log('subscription', message)
if(message != null && this.newMessageId != message.id) {
this.newMessageId = message.id;
this.messages.push(message);
this.scrollBottom(100);
}
})
Hey @yuth,
As the solution given by @RidClick isn't compliant with CI/CD and multiple branches/environments workflow, do we have any update on this point?
@yuth If I'm subscribed to onCreateSomething
and something gets created, I get an event to all my clients, whether I am authorized to see the data or not. It seems that this is the expected behavior. If so it's a big hole. This should be prioritized as a critical bug I would say because the default subscriptions compromise data privacy.
Btw - my auth flow is pretty complicated. I override the claims pre token generation and I assign the permissions there and then. After that, users are supposed to see what they're supposed to see only.
The same auth rules that apply to read
should apply to subscriptions.
Most helpful comment
@yuth If I'm subscribed to
onCreateSomething
and something gets created, I get an event to all my clients, whether I am authorized to see the data or not. It seems that this is the expected behavior. If so it's a big hole. This should be prioritized as a critical bug I would say because the default subscriptions compromise data privacy.Btw - my auth flow is pretty complicated. I override the claims pre token generation and I assign the permissions there and then. After that, users are supposed to see what they're supposed to see only.
The same auth rules that apply to
read
should apply to subscriptions.https://github.com/aws-amplify/amplify-cli/issues/1766