mayteio / use-pusher Goto Github PK
View Code? Open in Web Editor NEW๐ Easy as react/native hooks that integrate with the pusher-js library
Home Page: https://use-pusher-docs.netlify.com/
๐ Easy as react/native hooks that integrate with the pusher-js library
Home Page: https://use-pusher-docs.netlify.com/
The issue I'm having is that I have to send 3 messages to finally see the first one I sent.
I have an example repo to reproduce the issue but it's private, I don't mind sharing access if it will help.
Next js and Next API routes
Is this package still being actively maintained?
It's been over a year since the last commit and there seems to be a buildup of Dependabot PRs.
We use this package in production so it would be great to hear a status update on this!
Currently, I'm using usePusher in HoC to avoid this problem but if a child component subscribes to changes using useEvent it just invokes the first time, the second re-render will not provoke the callback to be invoked.
If you add usePusher into a child component i works like "once" event not not "on"
Just curious..
Also, this library is awesome! Great job. :)
Hi, is there a way to use encrypted channels with this library without forking?
https://pusher.com/docs/channels/using_channels/encrypted-channels/
To support encryption, the client needs to import a different path from pusher-js: https://github.com/pusher/pusher-js/tree/master#encrypted-channel-support
import Pusher from 'pusher-js';
import Pusher from 'pusher-js/with-encryption';
Any guidance is appreciated. Thanks!
We're using this package in a web product, and we're encountering issues during compilation because the type definitions reference the react-native
types, which we haven't installed in our product.
Could you consider vendoring (copying in) the types you need from React Native so we're able to use this package from web products?
For reference, this is the error from the TypeScript compiler:
Describe the bug
This package seems to be constrained to a React peer dependency if 16.x, making it incompatible with React 17 and 18 codebases.
I could find no reason in the code for this limitation. Any chance we could loosen up the peer dependency constraint to allow newer react projects to use this hook? :)
useChannel hooks automatically disconnect channels?
i use this hooks, i wonder useChannel hook automatically disconnect when component unmount?
import React from "react";
import { PusherProvider } from "@harelpls/use-pusher";
const config = {
// ...
logToConsole: true,
// ...
};
const App = () => {
<PusherProvider {...config}>
<Example />
</PusherProvider>;
};
I want this to be:
Pusher.logToConsole = true;
Hi, I'm trying to get the status of the connection. using
const { client } = usePusher();
useEffect(() => {
client.connection.bind('connected', () => {
console.log('Realtime is go!');
});
}, []);
but it's not working, any way to do this?
Describe the bug
Not a bug but an overall structural issue. Does this package ignore pusher presence, as we need user data for that right ?
To Reproduce
None
Is it possible to maintain the same connection while navigating pages in react-router?
For instance:
/join
route connects to presence channel and emits his name in a client eventhistory.replace('/start-game')
.I want the user to stay on the same connection because if I change route the user unsubscribes from the channel and I lose his name.
Hi, thanks for the library, I am starting to integrate it and it look very promising!
In useEvent hook, the data parameter is currently optional in the callback: callback: (data?: D, metadata?: { user_id: string }) => void
Is there any specific reason for that?
Can you provide a working presence channel via codesandbox? I need to get all subscribed members
I can't subscribe to my presence channel using the code provided here
First, I can't subscribe using only this config
const config = {
// required config props
clientKey: "<PUSHER_APP_KEY>",
cluster: "<PUSHER_APP_CLUSTER>",
// required for private/presence channels
// also sends auth headers to trigger endpoint
authEndpoint: "http://xx.xx.xx.xx/pusher/auth",
auth: {
headers: {
Authorization: "Bearer <AUTH TOKEN>",
}
}
};
I can successfully get a response from http://xx.xx.xx.xx/pusher/auth like so
{"auth":"1afff399e76480e04bfe:0c40bb0f16357b2a2cb85f2fb631ea75ff0df0a7c760b36b76e5839c83d7354as"}
then upon looking on dev console, there are no subscriptions at all and gets this message
{"event":"pusher:connection_established","data":"{\"socket_id\":\"3363.1846347\",\"activity_timeout\":120}"}
{"event":"pusher:error","data":{"code":4009,"message":"Connection not authorized within timeout"}}
UPDATE:
I even added channel_data property in the response but no luck based on the documentation of Pusher
https://pusher.com/docs/channels/server_api/authenticating-users
Authentication of a presence channel is performed in exactly the same way as a private channel but the JSON response must also have a channel_data property containing information that you wish to share about the current user
I propose that useEvent
hook should add metadata in its callback type since authenticated channels send them with the event.
Describe the bug
A clear and concise description of what the bug is.
Jest is installed as a dependency, not a dev dependency. This caused us some issues regarding module resolutions (specifically with Prisma and Decimal.js), throwing typescript errors due to the differences between latest version of Decimal.js (10.3.1) and the version used by Jest (10.2.0).
To Reproduce
Install Decimal.js and this package in the same repo. Decimal.js typings will be that of the version in jest (10.2.0), and not the latest (10.3.1).
I'm setting up PusherProvider on each separate page, so when user close tab or visit another page on a website, connection should close in order to save up pusher bandwidth. But connection only disconnects when user close tab, if user just leaves the page, connection is not closing and when user revisit the page a second connection will open, so now we have two connections instead on one.
To Reproduce
Sandbox link: https://codesandbox.io/s/use-pusher-disconnect-issue-1nz21
use-pusher: 7.2.1
react: 16.14.0
next: 10.0.4
This module is really great. Is there any chance it could be made to support React Native? Maybe in PusherProvider it could use require and choose between pusher-js
and pusher-js/react-native
? Or you could pass in a custom Pusher and require pusher-js
if one wasn't provided?
Android
"@react-native-community/netinfo": "3.2.1",
"react": "16.8.3",
"react-native": "0.59.9",
"@harelpls/use-pusher": "^7.0.0",
I'm trying to use presence channel with an event and trigger to send messages. I implement it like this gist
With presence-channel
instead of channel
.
(node:12428) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'length' of undefined
at Pusher.trigger (\app\node_modules\pusher\lib\pusher.js:144:13)
handler.post(async (req, res) => {
const { channelName, eventName, data } = req.body;
console.log(req.body);
req.pusher.trigger(channelName, eventName, data); //! The error occurs here
return res.status(200).json({
success: 'message sent',
message: data,
});
});
It works with Channel
but not presence-channel
Hi, is there a way to update auth config on demand?
https://github.com/pusher/pusher-js/tree/v7.6.0#channelauthorization-object
For example:
User access the site, we have web socket request without auth config
And user login their account, we need to disconnect previous client and create new client with auth config (for userAuthentication or channelAuthorization)
But it's not working as expected
previousConfig.current and props is the same value
@harelpls/[email protected]
[email protected]
Thanks!
There's a missing line in the useChannel
hook, inside the useEffect
function. The function needs to return this:
return () => client?.unsubscribe(channelName);
This way, then the channel name changes, the old channel gets unsubscribed. I tried this in a local copy and it worked. I would have made a PR but I couldn't get the project to build (most likely wrong typescript version or something like that) and I gave up.
The code,
useEffect(() => {
/** Return early if there's no client */
if (!client) return;
/** Return early and warn if there's no channel */
if (!channelName) {
console.warn(NO_CHANNEL_NAME_WARNING);
return;
}
/** Subscribe to channel and set it in state */
const pusherChannel = client.subscribe(channelName);
setChannel(pusherChannel as T);
/** Cleanup on unmount/re-render */
return () => client?.unsubscribe(channelName);
}, [channelName, client]);
will keep connecting to the channel even if the app is already connected to the same channel before. Can we have some kind of check before subscribing to the same channel?
Something like:
...
if (!channelName) {
console.warn(NO_CHANNEL_NAME_WARNING);
return;
}
if (isSubscribed(channelName)) {
return;
}
/** Subscribe to channel and set it in state */
const pusherChannel = client.subscribe(channelName);
setChannel(pusherChannel as T);
// Keep record of connected channels
addChannelToTheMap(channelName)
...
...
Or was this a design decision? In that case, if the user keep subscribing to the same channel, what she should do to remove the extra connections?
Fork pusher-js-mock
and improve that package. Remove from this one (including test dependencies).
Might need to use Proxies for adding myID to the channel, since any changes to the channel object directly result in all other instances of MockPusherClient.subscribe
inheriting the same ID. This has worked while testing other projects so far:
/**
* TODO: type this properly and move it to @harelpls/use-pusher
*/
class MockPusher {
public channels: any = {}
public channel(name: string) {
if (!this.channels[name]) {
this.channels[name] = new MockPusherChannel(name)
}
return this.channels[name]
}
public reset() {
MockPusherInstance.channels = {}
}
}
export const MockPusherInstance = new MockPusher()
export class MockPusherClient {
public id: string
public userInfo: Record<string, any>
constructor(id: string, userInfo: Record<string, any>) {
this.id = id
this.userInfo = userInfo
}
public subscribe(name: string) {
if (this.id && this.userInfo) {
const channel = MockPusherInstance.channel(name)
channel.members[this.id] = this.userInfo
setTimeout(() => {
const channel = MockPusherInstance.channel(name)
channel.trigger("pusher:subscription_succeeded", {
members: channel.members,
})
channel.trigger("pusher:member_added", {
id: this.id,
info: this.userInfo,
})
}, 1000)
return channel
}
}
public unsubscribe(name: string) {
if (this.id && this.userInfo) {
const channel = MockPusherInstance.channel(name)
channel.trigger("pusher:member_removed", {
id: this.id,
info: this.userInfo,
})
}
}
}
class MockPusherChannel {
public name: string
callbacks = {}
members = {}
subscribed: boolean = true
constructor(name: string) {
this.name = name
this.members = {}
this.callbacks = {}
}
/**
* Bind callback to an event name.
* @param {String} name - name of the event.
* @param {Function} callback - callback to be called on event.
*/
public bind(name: string, callback: () => void) {
this.callbacks[name] = this.callbacks[name] || []
this.callbacks[name].push(callback)
}
/**
* Unbind callback from an event name.
* @param {String} name - name of the event.
* @param {Function} callback - callback to be called on event.
*/
public unbind(name: string, callback: () => void) {
this.callbacks[name] = (this.callbacks[name] || []).filter(
cb => cb !== callback
)
}
/**
* Emit event with data.
* @param {String} name - name of the event.
* @param {*} data - data you want to pass in to callback function that gets called.
*/
public trigger(name: string, data?: any) {
const callbacks = this.callbacks[name]
if (callbacks) {
// console.info(`Triggered ${name} event with the following data:`, data)
callbacks.forEach((cb: (data?: any) => void) => {
cb(data)
})
}
}
}
Is there a way we can reconnect presence connection?
coz after some time, client stops receiving events
Hello there!
Can you change the way of importing pusher-js? They removed the encrypted channel support from the standard package.
Read here
Best Regards
MatsG23
Describe the bug
Thanks for a great library! If the following issue is as intended please disregard.
When a component with useChannel and useEvent is unmounted, the channel is unsubscribed from although other components are still subscribed. Thus subsequent events are not caught in the still mounted components.
This can be avoided by reorganising the component tree but seems hard to future proof.
To Reproduce
I will be happy to make a code sandbox but I'm not sure which Pusher app to connect to etc? Is the idea that I make the sandbox with placeholders and you enter your keys?
Sometimes you don't want to subscribe to a channel until another bit of data is available. It would be nice if you allowed useChannel
to accept undefined
, null
, or false
as a conditional to wait to subscribe. Similar to how useSWR
does it.
For instance:
const Messenger = () => {
const my = useMe()
const channelURL = my.username && `/api/messages/${my.username}`
const channel = useChannel(channelURL)
useEvent(channel, eventType, data => {
})
}
In the above example, this prevents sending a subscription request from happening until we get my.username
. Otherwise we would be subscribing to channel /api/messages/undefined
Describe the bug
Using usePusher in a React 18 TypeScript project throws the error:
Property 'children' does not exist on type 'IntrinsicAttributes & PusherProviderProps'.
This is because React 18 Requires children?: React.ReactNode
to be defined in the component props which is missing here.
Months ago i opened an issue regarding the event handler not being invoked, that issue was half fixed but it was related to the fact that usePusher sometimes do not re-bind (when the component/dependencies re-render or its just simply not registered on pusher.js)
What I would suggest is having a warning/error from usePusher when a pusher event is consumed on the client-side (via ws) but there are no handlers for it OR its simply not registered and it would help a lot debugging
This feature could be enabled in dev only or via some kind of debugging flag and would help a lot in identifying some issues
Hey, I enjoy using the package so far but I noticed a mistake with the "usePresenceChannel" documentation.
Instead of
{Object.entries(members)
// filter self from members
.filter([id] => id !== myID)
// map them to a list
.map([id, info] => (
<li key={id}>{info.name}</li>
))
}
It should be
{Object.entries(members)
// filter self from members
.filter(id => id !== myID)
// map them to a list
.map((info, id ) => ( // info 1st parameter, id 2nd
<li key={id}>{info.name}</li>
))
}
Correct me if I'm wrong, and maybe it's just on my end, but it took me some time to figure out ๐
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.