Closed nattive closed 1 year ago
In order to set your own headers you would need to use the onAuthorizer callback to provide your own way of calling your auth endpoint, including setting any available headers.
I got the same issue because to access the authEndpoint
need an Authorization header. It would be very helpful if someone could point out the solution or example, thanks.
@benw-pusher (or any pusher devs) — is there an example you could give here or elaborate on exactly how to do this?
The new documentation seems to lack an explanation of how to achieve this with this new RN lib (or if it is deep in there somewhere I'm sure I'm not the only one who'd love a nudge in the right direction 🙂).
All I've been able to find in the new docs is the onAuthorizer section in the README and generating authorization strings for what seems like the default Pusher auth endpoint...but nothing on how to provide the correct params for a custom authEndpoint
if it is provided.
TDLR...this config obj is how we got the pusher-js
lib to allow us to subscribe to private user channels previously, but there doesn't seem a trivial way to do this in the new lib.
const pusherConfig = {
...otherConfigStuff,
authEndpoint: <custom-endpoint>,
auth: {
headers: { Authorization: `Bearer ${apiUserToken}` },
}
}
Is there a way to achieve this or will we have to wait for some further development?
Also, a quick side note...once you land in the official pusher docs, it seems to only explain the pusher-js
way of doing things which is a bit confusing since some links in this repo point you there.
Works for me, call your endpoint with channelName and socketId parameters, backend return { auth, channel_data } information
@alexsymbol ty for the code snippets!
are you able to subscribe to private channels after doing the above? I see the onAuthorizer
call with the correct data being passed through, but no luck getting private events to show.
yes I can, check the onSubscriptionError methods to find out what the problem is
I am connecting the same way as commented above. However on iOS I am also not able to subscribe. Also, none of the error callbacks are being fired. Android works as intented.
pusher
.init({
apiKey: Config.PUSHSER_KEY,
cluster: Config.PUSHSER_CLUSTER,
async onAuthorizer(channelName, socketId) {
const token = await auth().currentUser?.getIdToken();
try {
const res = await fetch(Config.PUSHER_AUTH_ENDPOINT, {
method: "POST",
headers: new Headers({
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
}),
body: JSON.stringify({
socket_id: socketId,
channel_name: channelName,
}),
});
if (!res.ok) {
throw new Error(`Pusher: Received ${res.status} from ${res.url}`);
}
const data = await res.json();
return data;
} catch (error) {
console.error("Failed to authenticate");
}
},
onConnectionStateChange: (state) => {
console.info("Pusher:", state);
},
onSubscriptionSucceeded(channelName, data) {
console.info("Pusher: Subscribed to ", channelName, data);
},
onSubscriptionError(channelName, message, e) {
console.error("Pusher: Failed to subscribe to ", channelName, message, e);
},
onDecryptionFailure(eventName, reason) {
console.error("Pusher: Decryption failure", eventName, reason);
},
onError(message, code, e) {
console.error("Pusher: Error", message, code, e);
},
})
.then(() => {
pusher.connect();
})
.catch(console.error);
@sin2 your backend also expects fields _socketid and _channelname ?
Yes, and returns an object with an auth field. ie. { "auth" : "..." }
I think the problem with this line const data = await res.json(); Try to use destructuring without line above const { data } = await fetch(Config.PUSHER_AUTH_ENDPOINT, {,
Also try to remove this line
if (!res.ok) {
throw new Error(Pusher: Received ${res.status} from ${res.url}
);
}
P.S. you don't need to use try/catch, for catch an error you have onSubscriptionError method
Property 'data' does not exist on type 'Response'.ts
Fetch doesn't return a data property.
After removing the try/catch there is still no error being fired. Also, this is working for android devices.
@alexsymbol FWIW I am also seeing the same behavior as @sin2 on iOS...
onAuthorizer
is called + we've confirmed correct data is being returned. subscribe
fn is called with the private channelName
but none of the callbacks (on subscribe
OR top level pusher.init
) are being called.
Property 'data' does not exist on type 'Response'.ts
Fetch doesn't return a data property.After removing the try/catch there is still no error being fired. Also, this is working for android devices.
I use axios library for request
@sin2 @alexscarlett Try to use this syntax for channelName
const channelName = `presence-post-${adminId}-channel-${channel}`;
await pusher.subscribe({
channelName,
onSubscriptionSucceeded: data => {
console.log('data', data);
},
onSubscriptionError,
onEvent: async (event: PusherEvent) => {
console.log('event: ', event);
},
});
What would adminId and channel be in with this syntax?
this question already belongs to another topic, you can post your sample code in the topic with the ability to subscribe to the channel itself because the original question was about authorization problems
I think this is still an authorization problem. I know subscription works correctly given that it works on Android. Unless there is a difference I am not understanding between implementations on both platforms. At the very least, onAuthorizer should be better documented.
For now, I unfortunately have switched back to using the pusher-js library.
I should also add, that I am able to successfully subscribe to public channels.
edit: I suspect my issue is related to https://github.com/pusher/pusher-websocket-react-native/issues/34. After trying https://github.com/pusher/pusher-websocket-react-native/pull/36 I was able to successfully subscribe.
@sin2 We've just released 1.2.0 which solves this issue on iOS. We'll be working on fixing this issue on Android for the next releases.
ISSUE
I am using laravel as the backend for this package, i cant seem to find a way to set the bearer token at the header in other to subscribe to to a private channel.
Snippet