react-native-google-signin / google-signin

Google Sign-in for your React Native applications
https://react-native-google-signin.github.io/
MIT License
3.19k stars 878 forks source link

I need refresh token in react native using this google sign in packge #1205

Closed awais882s closed 10 months ago

awais882s commented 1 year ago

I need a refresh token in react native I only get access to the user please help me or any solutions on how to get a refresh token give me proper details or any other solution.... pleas reply me as soon as possible

const App = () => {
  const [isSignedIn, setIsSignedIn] = useState(false);
  const [userInfo, setUserInfo] = useState(null);
  const [loading, setLoading] = useState(false);
  const [accessToken, setAccessToken] = useState(null);

  useEffect(() => {
    GoogleSignin.configure({
      scopes: ['https://www.googleapis.com/auth/userinfo.profile', 'https://www.googleapis.com/auth/userinfo.email',
        'https://www.googleapis.com/auth/calendar', 'https://www.googleapis.com/auth/calendar.events', 'https://www.googleapis.com/auth/calendar.events.readonly',
        'https://www.googleapis.com/auth/calendar.readonly'
      ],
      webClientId: "',
      forceCodeForRefreshToken:true,
      offlineAccess:true

    });
  }, [])
  const SignIn = async () => {
    try {
      await GoogleSignin.hasPlayServices();
      const userInfo = await GoogleSignin.signIn();
      console.log('userInfo', userInfo)
      const accessToken = await GoogleSignin.getTokens();
      console.log('accessToken', accessToken)
      setAccessToken(accessToken);
      setUserInfo(userInfo);
      setIsSignedIn(true);
    } catch (error) {
      if (error.code === statusCodes.SIGN_IN_CANCELLED) {
        // user cancelled the login flow
      } else if (error.code === statusCodes.IN_PROGRESS) {
        // operation (e.g. sign in) is in progress already
      } else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
        // play services not available or outdated
      } else {
        // some other error happened
      }
    }
  };
  const SignOut = async () => {
    try {
      await GoogleSignin.signOut();
      setIsSignedIn(false);
      setUserInfo(null);
    } catch (error) {
      console.error('Sign out error:', error);
    }
  };
  return (
    <View style={{ justifyContent: "center", flex: 1, alignItems: "center" }}>
      {loading ? (
        <ActivityIndicator size="large" color="#0000ff" />
      ) : isSignedIn ? (
        <>
          <Text style={{ color: "black", fontSize: 20 }}>Name {userInfo?.user.name}</Text>
          <Text style={{ color: "black", fontSize: 20 }}>Email:{userInfo?.user.email}</Text>
          <Text style={{ color: "black", fontSize: 20 }}>google id:{userInfo?.user.id}</Text>
          {userInfo?.user.photo && <Image source={{ uri: userInfo.user.photo }} style={styles.profileImage} />}
          <Button title="Log Out" onPress={SignOut} />
        </>
      ) : (
        <>
          <GoogleSigninButton
            style={{ width: 192, height: 48 }}
            size={GoogleSigninButton.Size.Wide}
            color={GoogleSigninButton.Color.Dark}
            onPress={SignIn}

            disabled={loading} // Disable the button when loading is true
          />
        </>
      )}
    </View>
  )
}

export default App

const styles = StyleSheet.create({
  profileImage: {
    width: 100,
    height: 100,
    borderRadius: 50,
    marginTop: 10,
    marginBottom: 10
  },
})
kevingoss2 commented 11 months ago

I am facing the same issue. I need a way to refresh my token so my user is not logged out after an hour.

markmccoid commented 11 months ago

I'm using this in an IOS Environment and was also looking for a refresh token, however, I found that I did not need one.

I'm not sure how it works with Android, but once you signIn(), you can call getTokens(), which will return an AccessToken that can be used with Google APIs.

This access token will only be valid for an hour, but you can call getTokens() at anytime to get a valid access token WITHOUT having to sign in again.

vonovak commented 10 months ago

Hello and thanks for asking, it would help to know what you're trying to achieve. If the question is "how to get a refresh token", then you'd typically do this on a server, as outlined here https://developers.google.com/identity/protocols/oauth2/web-server#httprest_1 Thank you 🙂

miteshdevg commented 7 months ago

I am facing the same issue. I need a way to refresh my token so my user is not logged out after an hour.

I have a solution for it

you can use that code

` useEffect(() => { // const logout = async () => { // await AsyncStorage.removeItem("AccessToken"); // }; const refreshGoogleToken = async () => { try { await GoogleSignin.hasPlayServices(); const userInfo = await GoogleSignin.signIn(); const googleCredential = auth.GoogleAuthProvider.credential( userInfo.idToken );

    console.log("googleCredential", googleCredential);

    const userCredential = await auth().signInWithCredential(
      googleCredential
    );

    // get curent use id Token using getIdToken() method

    userCredential.user.getIdToken().then(async (idToken) => {
      console.log("idToken99999999", idToken);
      // store the token in async storage
      await AsyncStorage.setItem("AccessToken", JSON.stringify(idToken));
      // const token = `Bearer ${idToken}`;

      // let data = JSON.stringify({});

      // let config = {
      //   method: "post",
      //   maxBodyLength: Infinity,

// add your URL // headers: { // "Content-Type": "application/json", // Authorization: token, // }, // data: data, // };

      // axios
      //   .request(config)
      //   .then((response) => {
      //     console.log(JSON.stringify(response.data));
      //     setLoading(false);
      //   })
      //   .catch((error) => {
      //     setLoading(false);
      //     console.log(error);
      //   });
    });
  } catch (error) {
    console.log("err", error);
    if (error.code === "auth/id-token-expired") {
      try {
        const refreshtoken = await user.getIdToken(true);
        console.log("refreshtoken", refreshtoken);
      } catch (refreshError) {
        console.log("Error refreshing ID token:", refreshError);
        // Handle refresh token error
      }
    } else {
      // Handle other errors
    }
  }
};

const getTokens = async () => {
  const data = await AsyncStorage.getItem("AccessToken");

  const parts = data
    .split(".")
    .map((part) =>
      Buffer.from(
        part.replace(/-/g, "+").replace(/_/g, "/"),
        "base64"
      ).toString()
    );

  const payload = JSON.parse(parts[1]);

  console.log(Math.floor(Date.now() / 1000), "JWT payload", payload?.exp);
  Math.floor(Date.now() / 1000) >= payload?.exp
    ? refreshGoogleToken()
    : console.log("your token is up to date");
};
getTokens();

}, []); `

miteshdevg commented 7 months ago

@awais882s @vonovak @markmccoid @kevingoss2

first you have a token please decode it and after check inside object one key exp using this key you can check token expired timestamp

awais882s commented 7 months ago

@miteshdevg Thank You Brother