Next.js集成Pusher Presence Channel报错:Invalid user data求助
在Next.js中使用Pusher遇到"Invalid user data: 'presence-channel'"错误
我正在练习在Next.js中使用Pusher,遇到报错:Error: Invalid user data: 'presence-channel',多次尝试仍无法解决。以下是相关代码文件:
api/index.js 文件
import { pusher } from "../../../lib/pusher"; // presence channel handler export default async function handler(req, res) { const { message, username } = req.body; // trigger a new post event via pusher await pusher.trigger("presence-channel", "chat-update", { message, username, }); res.json({ status: 200 }); }
api/pusher/auth 文件
import { pusher } from "../../../../lib"; export default async function handler(req, res) { const { socket_id, channel_name, username } = req.body; const randomString = Math.random().toString(36).slice(2); const presenceData = { user_id: randomString, user_info: { username, }, }; try { var auth = pusher.authenticateUser(socket_id, channel_name, presenceData); res.send(auth); } catch (error) { console.error(error); } }
lib/index.js 文件
import Pusher from "pusher"; export const pusher = new Pusher({ appId: process.env.NEXT_PUBLIC_PUSHER_APP_ID, key: process.env.NEXT_PUBLIC_PUSHER_KEY, secret: process.env.NEXT_PUBLIC_PUSHER_SECRET, cluster: process.env.NEXT_PUBLIC_PUSHER_CLUSTER, useTLS: true, });
pages/chat.js 文件
import { useState, useEffect } from "react"; import Pusher from "pusher-js"; import axios from "axios"; export default function Chat({ username }) { const [message, setMessage] = useState(""); const [displayMessage, setDisplayMessage] = useState([]); const [onlineUserCount, setOnlineUserCount] = useState(0); console.log(process.env.NEXT_PUBLIC_PUSHER_APP_ID); const pusher = new Pusher(process.env.NEXT_PUBLIC_PUSHER_KEY, { cluster: "ap2", authEndpoint: `api/pusher/auth`, auth: { params: { username } }, }); useEffect(() => { const channel = pusher.subscribe("presence-channel"); channel.bind("pusher:subscription_succeeded", (members) => { setOnlineUserCount(members.count); }); channel.bind("pusher:member_added", (member) => { setOnlineUserCount(channel.member.count); setOnlineUserCount((prevState) => { [...prevState, { username: member.info.username }]; }); }); channel.bind("chat-update", (data) => { const { message, username } = data; setDisplayMessage((prevState) => { [...prevState, { message, username }]; }); }); return () => { pusher.unsubscribe("presence-channel"); }; }, []); const handleSubmit = async (e) => { e.preventDefault(); await axios.post("/api/pusher/chat-update", { message, username, }); }; return ( <div> {username} {displayMessage.map((chat, id) => { return <div key={id}>{chat.message}</div>; })} <form onSubmit={handleSubmit}> <input type="text" onChange={(e) => setMessage(e.target.value)} placeholder="Enter Message" /> </form> </div> ); }
pages/index.js 文件
import Head from "next/head"; export default function Home({ handleLoginChange, handleLogin }) { return ( <div> <Head> <title>Dealer</title> <meta name="description" content="Generated by create next app" /> <link rel="icon" href="/favicon.ico" /> </Head> <div> <form onSubmit={handleLogin}> <input type="text" placeholder="enter your username" onChange={handleLoginChange} /> <button>Login</button> </form> </div> </div> ); }
_app.js 文件
import "../styles/globals.css"; import { useState } from "react"; import { useRouter } from "next/router"; function MyApp({ Component, pageProps }) { const [username, setUsername] = useState(""); const router = useRouter(); const handleLogin = (e) => { e.preventDefault(); router.push("/chat"); }; return ( <Component handleLoginChange={(e) => setUsername(e.target.value)} username={username} handleLogin={handleLogin} {...pageProps} /> ); } export default MyApp;
问题分析与解决方案
这个错误的核心是Pusher服务端认证方法使用错误,加上前后端的细节疏漏,逐一修正如下:
1. 修正服务端认证方法
对于Presence频道,Pusher服务端正确的认证方法是authenticate(),而非authenticateUser()。修改api/pusher/auth文件:
import { pusher } from "../../../../lib"; export default async function handler(req, res) { const { socket_id, channel_name, username } = req.body; const randomString = Math.random().toString(36).slice(2); const presenceData = { user_id: randomString, user_info: { username, }, }; try { // 替换为正确的authenticate方法 const auth = pusher.authenticate(socket_id, channel_name, presenceData); res.send(auth); } catch (error) { console.error(error); res.status(500).json({ error: error.message }); } }
2. 修复前端依赖与状态更新逻辑
- 在
pages/chat.js的useEffect中,添加pusher和username到依赖数组,确保组件能正确响应变量变化:
useEffect(() => { const channel = pusher.subscribe("presence-channel"); // 其余bind逻辑保持不变 return () => { pusher.unsubscribe("presence-channel"); }; }, [pusher, username]); // 添加依赖
- 修正状态更新的返回逻辑,确保状态能正确更新:
// 修正pusher:member_added中的状态更新 channel.bind("pusher:member_added", (member) => { // 注意是channel.members.count,不是channel.member.count setOnlineUserCount(channel.members.count); }); // 修正chat-update中的状态更新 channel.bind("chat-update", (data) => { const { message, username } = data; setDisplayMessage((prevState) => { return [...prevState, { message, username }]; // 返回新数组 }); });
3. 修正API请求路径
chat.js中提交消息的API路径与实际文件路径不匹配,修改为:
const handleSubmit = async (e) => { e.preventDefault(); await axios.post("/api", { message, username, }); };
4. 统一环境变量配置
避免硬编码cluster,保持前后端环境变量一致:
const pusher = new Pusher(process.env.NEXT_PUBLIC_PUSHER_KEY, { cluster: process.env.NEXT_PUBLIC_PUSHER_CLUSTER, authEndpoint: `/api/pusher/auth`, // 加上斜杠避免路径问题 auth: { params: { username } }, });
完成以上修改后,重启应用即可解决该错误。
内容的提问来源于stack exchange,提问作者Swikar
相关产品推荐
相关产品推荐

