React开发LIFF应用调用liff.getProfile()返回undefined的求助
liff.getProfile() Returning Undefined in React LIFF App Hey there! Let's figure out why liff.getProfile() is giving you undefined and get your React LIFF app working properly. I've gone through your code and spotted a few key issues to fix:
1. Broken Promise Chain
Your current Promise chain isn't passing the profile data along correctly. When you call liff.getProfile() inside a then() block, you need to return its result so the next then() can receive it. Right now, that call doesn't get returned, so the final then() gets undefined instead of the profile object.
2. Deprecated Lifecycle Method
componentWillMount is deprecated in React (since version 16.3) and shouldn't be used for async operations like initializing LIFF. Instead, use componentDidMount—this runs after the component mounts, which is the right time to handle external API initializations.
3. Unhandled Login State Flow
You should check if the user is logged in after LIFF initializes, and only call getProfile() once login is confirmed (either the user was already logged in, or they completed the login redirect).
Fixed Class Component Code
Here's your App component with these fixes applied:
import React, { Component } from 'react'; import './App.css'; const liff = window.liff; const myliffId = 'xxxxxxxxxxxxxx'; // Replace with your actual LIFF ID class App extends Component { constructor() { super(); this.state = { text: '0' }; } componentDidMount = async () => { try { // Initialize LIFF first await liff.init({ liffId: myliffId }); // Check if user is logged in if (!liff.isLoggedIn()) { // Redirect to login, then come back liff.login({ redirectUri: 'https://11d493b7e4c8.ngrok.io' }); return; // Exit early since we're redirecting } // If logged in, fetch profile const profile = await liff.getProfile(); console.log(profile); this.setState({ text: profile.userId }); } catch (err) { console.error('LIFF initialization or profile fetch failed:', err); } }; print = () => { console.log(55555); }; render() { return ( <div> hi <button>ho</button> <div className="buttonGroup"> {/* Use className instead of class in React */} <div className="buttonRow"> <button id="openWindowButton" onClick={this.print}>{this.state.text}</button> <button id="closeWindowButton" onClick={this.print}>Close LIFF App</button> </div> </div> </div> ); } } export default App;
Bonus: Modern Function Component Version
Since React now recommends function components with hooks, here's how you could rewrite this using useEffect and useState—it's often cleaner for async operations:
import React, { useEffect, useState } from 'react'; import './App.css'; const liff = window.liff; const myliffId = 'xxxxxxxxxxxxxx'; function App() { const [userId, setUserId] = useState('0'); useEffect(() => { const initLiff = async () => { try { await liff.init({ liffId: myliffId }); if (!liff.isLoggedIn()) { liff.login({ redirectUri: 'https://11d493b7e4c8.ngrok.io' }); return; } const profile = await liff.getProfile(); setUserId(profile.userId); } catch (err) { console.error('Error:', err); } }; initLiff(); }, []); // Empty dependency array runs once on mount const print = () => console.log(55555); return ( <div> hi <button>ho</button> <div className="buttonGroup"> <div className="buttonRow"> <button id="openWindowButton" onClick={print}>{userId}</button> <button id="closeWindowButton" onClick={print}>Close LIFF App</button> </div> </div> </div> ); } export default App;
Additional Checks
- Make sure your LIFF app is configured correctly in the LINE Developers Console:
- The redirect URI matches exactly what you're using (including
https—LIFF requires HTTPS for production, and ngrok works for development) - Your LIFF app has the "Profile" permission enabled (you can set this under the "Permissions" tab in your LIFF app settings)
- The redirect URI matches exactly what you're using (including
- Clear your browser cache and test again—sometimes old login sessions can cause issues.
Hope this gets your app up and running! 🚀
内容的提问来源于stack exchange,提问作者Peter24

