I have build up a project using Next.js. Here I have wanted to implement a feature using the YouTube Data API. The feature is when the user clicks the youtube connect button, a pop-up window opens and authenticates the user. After the authentication, the YouTube Data API gives a response which contains the basic info the user's channel. Sometimes it has worked fine. But, sometimes it has shown the following error:
Here is my code:
import { Fragment, useEffect, useContext } from "react";
import {gapi} from "../common/api";
import { GOOGLE_CLIENT_ID } from "../../helpers/Constants";
import { AthleteContext } from "../../context/AthleteContextProvider";
import { Button, message } from "antd";
import AthleteProfileService from "../../services/AthleteProfileService";
const YouTubeConnect = () => {
const athleteContext = useContext(AthleteContext);
function authenticate() {
return gapi.auth2.getAuthInstance()
.signIn({scope: "https://www.googleapis.com/auth/youtube.readonly"})
.then(function() { console.log("Sign-in successful"); },
function(err) { console.error("Error signing in", err); });
}
function loadClient() {
gapi.client.setApiKey(GOOGLE_API_KEY);
return gapi.client.load("https://www.googleapis.com/discovery/v1/apis/youtube/v3/rest")
.then(function() { console.log("GAPI client loaded for API");
execute();
},
function(err) { console.error("Error loading GAPI client for API", err); });
}
// Make sure the client is loaded and sign-in is complete before calling this method.
function execute() {
return gapi.client.youtube.channels.list({
"part": "snippet,contentDetails,statistics",
"mine": true
})
.then(function(response) {
// Handle the results here (response.result has the parsed body).
console.log("Response", JSON.parse(response.body));
athleteContext.invokeYoutubeInfo(response.body);
AthleteProfileService.connectSocialAccount({
attrName: "youtube",
attrValue: JSON.parse(response.body).items[0].id
}).then(res => {
message.success("Youtube profile link added!");
athleteContext.setProfileUpdateStatus(true);
}).catch(err => {
console.log(err);
athleteContext.setProfileUpdateStatus(false);
})
},
function(err) { console.error("Execute error", err); });
}
function executeFinal() {
authenticate().then(() => {
loadClient();
})
}
gapi.load("client:auth2", function() {
gapi.auth2.init({client_id: GOOGLE_CLIENT_ID});
});
return (
<Fragment>
{/* <button onClick={() => authenticate().then(() => loadClient())}>auth</button> */}
<Button onClick={() => executeFinal()}>Connect</Button>
</Fragment>
)
}
export default YouTubeConnect;
I have tried some solutions. But, it still shows the error. Please tell me where is the problem.
Thanks in advance.
Related
I have a reactjs app which is connected to a oneSignal app for web notifications.
here are my config for oneSignal
function OneSignalInit(appid) {
await OneSignal.init({
appId: appid
});
OneSignal.showSlidedownPrompt();
}
function initOneSignal(appId) {
/* Call push notification */
try {
return OneSignalInit(appId);
} catch (error) {
return console.log(error);
}
}
function App() {
useEffect(() => {
if (!hasPlayerId) {
hasPlayerId = true;
initOneSignal(process.env.REACT_APP_NOTIFICATION).then(async () => {
OneSignal.getUserId((userId) => {
if (userId) {
console.log('🔔 ~ Player ID', userId);
}
});
});
}
}, []);
return (<div>OneSignal App</div>)
}
when i run it the app is connected and i receive the notifications fine, but after awhile I get this error
GET https://onesignal.com/api/v1/apps/APP_ID/icon net::ERR_CONNECTION_RESET
after that i can't get any notifications until i clear the browser cache and reload the page.
Any idea why it happens and how to restart the connection without having to clear the browser cache?
I've got a react front end that performs some actions. The relevant axios requests look like so:
const login = async () => {
await Axios.post('http://localhost:8000/login', {
username: username,
password: password,
}).then((response) => {
console.log("login response: ", response);
window.location.href = "http://localhost:3000/";
}).catch(err => {
alert(err.response.data);
});
};
// run on first render to see if user session is still active - remove console log later
useEffect(() => {
Axios.get("http://localhost:8000/isLoggedIn").then((response) => {
console.log("isLoggedIn resonse: ", response);
if (response.data.loggedIn === true) {
setLoginStatus(`Logged in as ${response.data.user}`);
}
})
}, [])
const Logout = async () => {
try {
await Axios.get('http://localhost:8000/logout').then((response) => {
console.log(response);
window.location.href = "http://localhost:3000/login";
}).catch(err => {
alert(err);
});
} catch (error) {
alert(error)
}
};
I keep having to press log out twice to actually log my user out. The logout route runs before the "isLoggedIn" route, according to my network tab. And it's successful, too. Here are the isLoggedIn and logout routes in my express backend:
export function isLoggedIn( req: any, res: any) {
if (req.session.user) {
// if our session already has a user, send true to the frontend
// frontend runs this get login on first render, so will have user data if cookie has not expired.
res.send({loggedIn: true, user: req.session.user})
} else {
res.send({loggedIn: false});
}
}
export function logout(req: any, res: any) {
if (req.session) {
req.session.destroy( (err: any) => {
if (err) {
res.status(400).send('Unable to log out');
} else {
res.send("Logout successful");
}
});
} else {
res.end();
}
}
I'm getting a successful logout. I just cannot figure out why I need to hit the logout button twice on the frontend to actually destroy the session and log the user out? Is there something timing related that I may be missing here?
I am creating an app with TypeScript + Firebase. I've followed this website to set it up: https://rnfirebase.io. After I finished with authentication I wanted to get a value from the real time database. However making the request doesn't resolve. I've also put it in the await version however that didn't resolve either.
import React, { useEffect } from "react";
import { Text } from "react-native";
import { firebase } from "#react-native-firebase/database";
import { REALTIME_DATABASE_ENV } from "react-native-dotenv";
const TestPage = () => {
useEffect(() => {
const reference = firebase
.app()
.database(REALTIME_DATABASE_ENV)
.ref("particularities/")
.once("value")
.then((snapshot) => {
console.log(`snapshot: ${snapshot.val()}`);
//expected result:
// {
// sickness: {
// label: "Sickness",
// },
// allergic: {
// label: "Allergic",
// },
// };
})
.catch((e: unknown) => {
console.log(`catch: ${e}`);
});
}, []);
return (
<Text>Test page</Text>
);
};
export default TestPage;
The rules that are applied to the real time database:
{
"rules": {
".read": false,
".write": false,
// ...
"particularities": {
".read": true,
".write": true,
},
}
}
Thing we found: logging out of the app does resolve all the requests made. Testing while logged in and all rules set to public gives the same result as before with the promise not resolving
As per the documentation here is how you can read the data once.
https://rnfirebase.io/database/usage#one-time-read
You don't need to pass database ref other than an 'us-central1'
import database from '#react-native-firebase/database';
database()
.ref('particularities/')
.once('value')
.then(snapshot => {
console.log('Data: ', snapshot.val());
})
.catch((e: unknown) => {
console.log(`catch: ${e}`);
});
I'm trying to implement google sign in in my expo using expo-auth-session,
When I click on my gmail to sign in, I'm redirected to this screen saying "Something went wrong when trying to finish signing in. Please close this screen to go back to the app".
//Google auth code:
import * as Google from 'expo-auth-session/providers/google';
const [request, response, promptAsync] = Google.useAuthRequest({
expoClientId: config.google.expoClientId,
redirectUri: config.google.redirectUri,
});
React.useEffect(() => {
//Handle google login
console.log(response)
if (response?.type === 'success') {
const { authentication } = response;
}
}, [response]);
//Button that calls the google sign in
<Button iconName={'google'} iconPressed={() => promptAsync({useProxy: true})} />
If someone is trying this now.
You can Follow This https://www.youtube.com/watch?v=hmZm_jPvWWM
In the code given in this video
replace promptAsync({useProxy: false, showInRecents: true}) => promptAsync()
I ended up using expo-google-app-auth, for some reason that I'm yet to figure out, you have to use host.expo.exponent as your package name and bundle identifier in the google developer console for this library to work.
Code:
import { Alert } from 'react-native';
import * as Google from 'expo-google-app-auth'
const GoogleLogin = async () => {
//Get those keys from the google developer console
const { iosClientId, androidClientId } = config.google
const { type, user } = await Google.logInAsync({
iosClientId,
androidClientId,
});
if (type === 'success') {
/* `accessToken` is now valid and can be used to get data from the Google API with HTTP requests */
return { email: user.email, id: user.id }
} else {
Alert.alert("Google login error.")
}
}
export default GoogleLogin;
I think you can try like this
import * as Google from 'expo-auth-session/providers/google';
import * as WebBrowser from 'expo-web-browser';
WebBrowser.maybeCompleteAuthSession();
....
const [request, response, promptAsync] = Google.useAuthRequest({
androidClientId: config.androidClientId,
iosClientId: config.iosClientId,
expoClientId: config.expoClientId,
scopes: config.scopes,
});
useEffect(() => {
if (response?.type === 'success') {
const { authentication } = response;
getGoogleUser((authentication as any).accessToken)
}
}, [response]);
const getGoogleUser = async (accessToken: string) => {
try{
const response = await fetch('https://www.googleapis.com/userinfo/v2/me', {
headers: { Authorization: `Bearer ${accessToken}`}
});
const user = response.json()
if (user?.email) {
const { email, name } = user; // you will get more data in the user object
.......
}
}
catch(error){
console.log('GoogleUserReq error: ', error);
}
}
return (
<View>
<Button
onPress={() => promptAsync() }
/>
</View>
);
I know and know how to do it but it causes problems for me
I just want to import the functions {OnSubmitLog_In and username} and maybe more how to listing it right is not going to make it a problem
2 js files
the first is imports like this
import * as Login from './log_in';
import { OnSubmitLog_In, username } from './log_in';
In the second file
async function OnSubmitLog_In(e) {
e.preventDefault();
var data = { username, password }
await axios.post("http://localhost:4000/users/signin", data, {
}).then((response) => {
if (localStorage.getItem('token', response.data.accessToken)) {
alert('user alredy in')
} else {
alert('hellow ' + data.username)
localStorage.setItem('token', response.data.accessToken)
console.log('response data', response.data)
console.log('response config', response.config.data)
}
}, (error) => {
console.log('error', error)
if (405) {
alert('user not found')
} else if (500) {
alert('user not found try again')
}
});
}
export default Log_In;
this is the error
./src/NAVBAR/nav.js
Attempted import error: 'OnSubmitLog_In' is not exported from './log_in'.
You are exporting as default, you should import like this,
import OnSubmitLog_In from './log_in'; //Not sure about username
Update
To import everything from a single file as,
import * as Login from './log_in'
You need to export everything as named export from log_in file.
For example, this is my log_in file,
import React from 'react'
export const MyComponent = () => {
return <div>Component 1</div>
}
export const MyComponent2 = () => {
return <div>Component 2</div>
}
Now you can use those components in parent component like,
<Login.MyComponent />
<Login.MyComponent2 />
Demo
You should export you functions in an object to import them the way you do.
Like this:
async function OnSubmitLog_In(e) {
e.preventDefault();
var data = { username, password }
await axios.post("http://localhost:4000/users/signin", data, {
}).then((response) => {
if (localStorage.getItem('token', response.data.accessToken)) {
alert('user alredy in')
} else {
alert('hellow ' + data.username)
localStorage.setItem('token', response.data.accessToken)
console.log('response data', response.data)
console.log('response config', response.config.data)
}
}, (error) => {
console.log('error', error)
if (405) {
alert('user not found')
} else if (500) {
alert('user not found try again')
}
});
}
export {
OnSubmitLog_In
};
You have to import code as below.
import OnSubmitLog_In, { username } from './log_in';
Here you are exporting as default. If you remove default then you have to write code as below.
import { OnSubmitLog_In, username } from './log_in';