appwrite/sdk-for-react-native

🚀 Feature: Oauth2 does not automatically redirect in React Native?

Opened this issue · 3 comments

đź”– Feature description

moved from appwrite issue #8867

I wasn't sure if I should be putting this under bug report, enhancement, or documentation, but considering I'm newer to expo+appwrite+react native, I decided to put this under enhancement because this may be intentional.

The documentation of Oauth2 / google seems like account.createOAuth2Session(OAuthProvider.Google); should automatically open the login page for the Oauth2 provider.

Image

However upon trying this in code, it seems to give the URI. And on mobile, no browser window or redirect occurs - the same screen still displays.

export const googleLogin = async () => { // Add async here to handle the session creation
  try {
    console.log('Initiating Google login...');
    // Create the OAuth2 session URL
    const uri = await account.createOAuth2Session('google');
    console.log(uri);
    
  } catch (error) {
    console.error('Error during Google login:', error);
  }
};

Image

I tried both the appwrite and react-native-appwrite libraries, and both seem to have a similar effect.

🎤 Pitch

As a newer user of appwrite, this was super confusing. I thought the mobile application would redirect me or open a new window with the URI containing the Oauth2 provider's login portal just by invoking the createOAuth2Session method. This is not the case, even with any of the optional parameters.

đź‘€ Have you spent some time to check if this issue has been raised before?

  • I checked and didn't find similar issue

🏢 Have you read the Code of Conduct?

And once again

For those of you who may be new and have a similar situation, here is the setup I've ended up using so far. At least it actually opens up google authentication, but now i have to figure out success/failure URLs. There is probably a lot of bloat even though I've removed some already and I've left some other parts out of my specific implementation, but this is what I was expecting appwrite to handle at least of opening the login screen natively :/.

import React, { useState } from 'react';
import { View, Text, TextInput, TouchableOpacity, Alert, useColorScheme } from 'react-native';
import { Colors } from '../../constants/Colors';
import { Svg, Path } from 'react-native-svg'; // For rendering SVG icons
import { googleLogin} from '../../lib/auth';  // Adjust path accordingly
import { useRouter  } from 'expo-router';
import { Client, Account, ID, Models } from 'react-native-appwrite';
import * as WebBrowser from 'expo-web-browser';

import "../../constants/global.css";

let client: Client;
let account: Account;

client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1')
.setProject('YOUR_PROJECT_ID')
.setPlatform('YOUR_BUNDLE_IDENTIFIER');

account = new Account(client);

const Login: React.FC = () => {

  const [loginUri, setLoginUri] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);

  const router = useRouter();

  const handleGoogleLogin = async () => {
      const uri = await googleLogin();  
      let result = await WebBrowser.openAuthSessionAsync(uri);
      return result;
  };

  const colorScheme = useColorScheme(); // Detects the current theme (light or dark)
  const colors = Colors[colorScheme === 'dark' ? 'dark' : 'light'];

  const [loggedInUser, setLoggedInUser] = useState<Models.User<Models.Preferences> | null>(null);
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [name, setName] = useState('');

  const handleAppleLogin = () => {
    appleLogin();
  };
  return (
       <View className={`flex-1 justify-center p-5 bg-[${colors.background}]`}  style={{ backgroundColor: 'white' }}>
              <TouchableOpacity
        className="flex flex-row items-center justify-center h-12 rounded-md bg-white mt-4"
        onPress={handleGoogleLogin}
      >
        <Svg width={24} height={24} viewBox="0 0 24 24" fill="none">
          <Path
            d="M21.35 11.1H12v2.67h5.31C16.84 15.9 14.7 17.6 12 17.6a5.6 5.6 0 010-11.2c1.43 0 2.73.53 3.73 1.4l2.02-2.02A8.85 8.85 0 0012 2.8a8.8 8.8 0 108.81 8.3c0-.4-.04-.8-.1-1.2z"
            fill="#4285F4"
          />
          <Path
            d="M3.44 7.2l2.46 1.8A5.6 5.6 0 0112 6.4c1.43 0 2.73.53 3.73 1.4l2.02-2.02A8.85 8.85 0 0012 2.8 8.8 8.8 0 003.44 7.2z"
            fill="#34A853"
          />
          <Path
            d="M12 17.6a5.6 5.6 0 004.06-1.6l-2.46-2.12a3.57 3.57 0 01-5.31-1.08l-2.46 1.8A8.8 8.8 0 0012 17.6z"
            fill="#FBBC05"
          />
          <Path
            d="M21.35 11.1H12v2.67h5.31A5.7 5.7 0 0112 17.6a5.8 5.8 0 01-5.68-4H12v-2.5H6.32a5.5 5.5 0 01-5.68 4.8A8.8 8.8 0 0012 21.2a8.8 8.8 0 008.81-8.3c0-.4-.04-.8-.1-1.2z"
            fill="#EA4335"
          />
        </Svg>
        <Text className="ml-3 text-[16px] text-black">Sign in with Google</Text>
      </TouchableOpacity>
      </View>
  );
};
export default Login;
import { account } from './appwrite' 

export const googleLogin = async () => { // Add async here to handle the session creation
    return await account.createOAuth2Session('google');
};
import { Client, Account, ID, Models } from 'appwrite';

const client = new Client()
client
  .setEndpoint('https://cloud.appwrite.io/v1')// The Appwrite API endpoint
  .setProject('YOUR_PROJECT_ID')
export const account = new Account(client)

Je pense qu'il faut extraire l'url je n'ai pas encore tester const handleGoogleLogin = async () => {
try {
// Obtenir l'URL pour la connexion Google
const uri = await googleLogin();

// Ouvrir une session d'authentification
let result = await WebBrowser.openAuthSessionAsync(uri);

if (result.type === "success") {
  // Vérifiez si une session est créée
  const session = await account.get();
  setLoggedInUser(session.user); // Mettre Ă  jour l'Ă©tat utilisateur
  
  // Rediriger vers une autre page après connexion réussie
  router.push("/home"); // Remplacez "/home" par la page cible
} else {
  Alert.alert("Erreur", "La connexion a échoué ou a été annulée.");
}

} catch (error) {
console.error("Erreur lors de la connexion avec Google:", error);
Alert.alert("Erreur", "Impossible de se connecter pour le moment.");
}
};

It's essential for a BaaS solution to correctly handle OAuth2 logins and for the second most-starred SDK (with a large gap to the 3rd) of Appwrite, I thought it would be feature-complete.
Any estimate on when this will be implemented?