pusher-channels-flutter
pusher-channels-flutter copied to clipboard
Can't Subscribe to Private Channel
I am attempting to subscribe to a private channel. The following is the instantiation of Pusher:
PusherChannelsFlutter pusher = PusherChannelsFlutter.getInstance();
var myChannelName = 'private-MyChannel';
try {
await pusher.init(
apiKey: '85fa4e3311f746a5ce25',
cluster: 'us2',
//authEndpoint: "https://9d1afc49846e.ngrok.io/mapi/auth",
onConnectionStateChange: onConnectionStateChange,
onError: onError,
onSubscriptionSucceeded: onSubscriptionSucceeded,
onEvent: onEvent,
onSubscriptionError: onSubscriptionError,
onDecryptionFailure: onDecryptionFailure,
onMemberAdded: onMemberAdded,
onMemberRemoved: onMemberRemoved,
onAuthorizer: onAuthorizer
);
await pusher.subscribe(channelName: myChannelName);
await pusher.connect();
} catch (e) {
print("ERROR: $e");
}
Given it's a private channel onAuthorizer get's called:
dynamic onAuthorizer(String channelName, String socketId, dynamic options) {
print('////onAuthorizer');
var response = Api().post('auth', {
"socket_id": socketId,
"channel_name": channelName,
});
var data = null;
response.then((response){
data = response.data;
return jsonDecode(data); // {"auth":"<redacted>:<redacted>"}
});
}
On Pusher's debug console the Subscribed event never gets triggered.
Do you receive any error messages when the subscription is attempted? You should see these in the client, or alternatively some error messages will be present in the Pusher Dashboard under the Error Log section?
It looks like your onAuthorizer
code is making a request to an endpoint, can you share the code that returns the auth token from that endpoint?
I received no success nor error message on the subscription. These are the callbacks I have defined:
void onSubscriptionSucceeded(String channelName, dynamic data) {
print("onSubscriptionSucceeded: $channelName data: $data");
}
void onSubscriptionError(String message, dynamic e) {
print("onSubscriptionError: $message Exception: $e");
}
Here's my controller from my Laravel app:
<?php
namespace App\Http\Controllers\MobileApi;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Pusher\Pusher;
class PusherAuthController extends Controller
{
public function __invoke(Request $request)
{
\Log::info('PusherAuthController', $request->toArray());
$pusher = new Pusher(
env('PUSHER_MOBILE_APP_KEY'),
env('PUSHER_MOBILE_APP_SECRET'),
env('PUSHER_MOBILE_APP_ID')
);
$channel = request('channel_name');
$socket_id = request('socket_id');
return $pusher->socket_auth($channel, $socket_id);
}
}
This produces a response in the following format:
{"auth":"<redacted>:<redacted>"}
I would expect that, if this authController is returning the auth token in the correct format (which it appears to be) then there should be an error emitted at the client. This error would likely be to indicate that the token returned is incorrect in some way. Are you able to open a support ticket so we can look up your app details and you can share the generated token and investigate? You can do so at support.pusher.com.
I'll put in a ticket. My theory is that with onAuthorizer there's an async request to call my endpoint. Technically that method would return null before the API request completed.
If authParams can offer support for Android and iOS this would resolve my issue.
Can you try something like:
dynamic onAuthorizer(String channelName, String socketId, dynamic options) async {
print('////onAuthorizer');
var response = await Api().post('auth', {
"socket_id": socketId,
"channel_name": channelName,
});
return jsonDecode(response.data);
}
I tried that but found that it only worked with public channels.
This worked for me.
When using the onAuthorizer method, don't set the authEndpoint option when initializing pusher.
Future<void> _initializePusher() async {
//singleton pusher instance
var pusher= PusherChannelsFlutter.getInstance();
await pusher.init(
apiKey: pusherData.apiKey,
cluster: pusherData.cluster,
onError: onError,
onEvent: onEvent,
onSubscriptionError: onSubscriptionError,
onAuthorizer: onAuthorizer);
channel = (await pusher.subscribe(channelName: channelName));
await pusher.connect();
}
dynamic onAuthorizer(
String channelName, String socketId, dynamic options) async {
var authUrl = baseUrl + '/broadcasting/auth';
var result = await post(
Uri.parse(authUrl),
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ${token}',
},
body: 'socket_id=' + socketId + '&channel_name=' + channelName,
);
return jsonDecode(result.body);
}
This worked for me.
When using the onAuthorizer method, don't set the authEndpoint option when initializing pusher.
Future<void> _initializePusher() async { //singleton pusher instance var pusher= PusherChannelsFlutter.getInstance(); await pusher.init( apiKey: pusherData.apiKey, cluster: pusherData.cluster, onError: onError, onEvent: onEvent, onSubscriptionError: onSubscriptionError, onAuthorizer: onAuthorizer); channel = (await pusher.subscribe(channelName: channelName)); await pusher.connect(); }
dynamic onAuthorizer( String channelName, String socketId, dynamic options) async { var authUrl = baseUrl + '/broadcasting/auth'; var result = await post( Uri.parse(authUrl), headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': 'Bearer ${token}', }, body: 'socket_id=' + socketId + '&channel_name=' + channelName, ); return jsonDecode(result.body); }
Hi, do you use laravel websockets pusher replacement method, if so where i have to set the Host name/address when initiate Pusher?
@yacinegithub this https://github.com/pusher/pusher-channels-flutter/issues/41#issuecomment-1101549333 could help you
This worked for me. When using the onAuthorizer method, don't set the authEndpoint option when initializing pusher.
Future<void> _initializePusher() async { //singleton pusher instance var pusher= PusherChannelsFlutter.getInstance(); await pusher.init( apiKey: pusherData.apiKey, cluster: pusherData.cluster, onError: onError, onEvent: onEvent, onSubscriptionError: onSubscriptionError, onAuthorizer: onAuthorizer); channel = (await pusher.subscribe(channelName: channelName)); await pusher.connect(); }
dynamic onAuthorizer( String channelName, String socketId, dynamic options) async { var authUrl = baseUrl + '/broadcasting/auth'; var result = await post( Uri.parse(authUrl), headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': 'Bearer ${token}', }, body: 'socket_id=' + socketId + '&channel_name=' + channelName, ); return jsonDecode(result.body); }
Hi, do you use laravel websockets pusher replacement method, if so where i have to set the Host name/address when initiate Pusher?
Same issue here, how can I insert custom port and host?
@lailai0715 You don't need those information. See the initialization here or my comment https://github.com/pusher/pusher-channels-flutter/issues/41#issuecomment-1101549333
how to get socketId()?
Dear @solpreneur I get null from broadcusting/auth
this is init
try {
await pusher.init(
apiKey: _apiKey.text,
cluster: _cluster.text,
onConnectionStateChange: onConnectionStateChange,
onError: onError,
onSubscriptionSucceeded: onSubscriptionSucceeded,
onEvent: onEvent,
onSubscriptionError: onSubscriptionError,
onDecryptionFailure: onDecryptionFailure,
onMemberAdded: onMemberAdded,
onMemberRemoved: onMemberRemoved,
//authEndpoint: "https://my-website.com/broadcasting/auth",
onAuthorizer: onAuthorizer,
);
await pusher.subscribe(channelName: _channelName.text);
await pusher.connect();
} catch (e) {
print("$e");
log("ERROR: $e");
}
and this is the onAuthorizer function
dynamic onAuthorizer(
String channelName, String socketId, dynamic options) async {
var authUrl = "https://my-website.com/broadcasting/auth";
var result = await http.post(
Uri.parse(authUrl),
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ${token}',
},
body: 'socket_id=' + socketId + '&channel_name=' + channelName,
);
return jsonDecode(result.body);
}
I tried content-type as json too but same result
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ${token}',
}
this is the error I get
[ +65 ms] I/PusherChannelsFlutter(20214): Start com.pusher.client.Pusher@4083fc0
[ +102 ms] I/flutter (20214): LOG: Connection: CONNECTING
[+1566 ms] I/flutter (20214): LOG: Connection: CONNECTED
[+1566 ms] I/flutter (20214): LOG: onSubscriptionError: Unable to parse response from Authorizer: null Exception: com.pusher.client.AuthorizationFailureException: Unable to parse
response from Authorizer: null
the backend is Laravel the route broadcasting/auth
is bydefault created
@ziagit An empty response from broadcast/auth could indicate an error when generating the necessary token - for example the broadcast driver not being set correctly to the app credentials in the .env file being missing/invalid.
@kwul0208 you can get the socket ID using the method described at https://github.com/pusher/pusher-channels-flutter#socket-information
@benw-pusher can you provide a method to send AuthOptions with pusher.init i think it will solve the problem
I solved this problem, if anyone else has such a problem look here