Expo React Native TypeScript Firebase v9でユーザー認証 ④【Login & Sign up】

code

firebaseのログインメソッド

今回はfirebase Authenticationのログインとサインアップについてです. ログインはsignInWithEmailAndPasswordメソッドを呼び出します. 引数にfirebase.tsのauthと、ユーザーが入力したメールアドレス、パスワードを渡します. サインアップはSignUp.tsxに遷移させます. Login.tsxに下記を追記します.

Login.tsx

import { StackNavigationProp } from '@react-navigation/stack';
import { ParamListBase } from '@react-navigation/native';
import { signInWithEmailAndPassword } from 'firebase/auth';
import { auth } from '../firebase';

const Login = (): JSX.Element => {

  const navigation = useNavigation<StackNavigationProp<ParamListBase>>();
  const [email, setEmail] = useState<string>('');
  const [password, setPassword] = useState<string>('');
  const [validationMessage, setValidationMessage] = useState<string>('');

  // ログイン
  const handleLogin = () => {
    try {
      signInWithEmailAndPassword(auth, email, password);
    } catch (error) {
      if (error instanceof Error) {
        setValidationMessage(error.message);
      }
    };
  }

  return (
    <View style={styles.container}>
      <View style={styles.inputContainer}>
        
        //  <----(中略)---->
      <View style={styles.buttonContainer}>
        <TouchableOpacity
          onPress={handleLogin}    // ここを追加
          style={styles.button}
        >
          <Text style={styles.buttonText}>Login</Text>
        </TouchableOpacity>
        <Text>Don't have an account yet?</Text>
        <TouchableOpacity
          onPress={() => navigation.navigate('Sign Up')}    // ここを追加
          style={[styles.button, styles.buttonOutline]}
        >
          <Text style={styles.buttonOutlineText}>Sign Up</Text>
        </TouchableOpacity>
      </View>
    </View>
  )
}

firebaseのサインアップメソッド

次にサインアップ画面です. サインアップ画面は画像のようなイメージです. メールアドレスとパスワードを2回入力する設定にします. パスワードについて、文字数や英数字記号大文字を含む、といった脆弱性のリスク対策の考え方については主題からそれますので、ここでは触れません. 

サインアップは引数にfirebase.tsのauthと、ユーザーが入力したメール アドレスとパスワードをcreateUserWithEmailAndPasswordメソッドに渡します。アカウントが作成された後、ログイン画面に遷移させます.

SignUp.tsx

const SignUp = () => {

  const navigation = useNavigation<StackNavigationProp<ParamListBase>>();

  const [email, setEmail] = useState<string>('');
  const [password, setPassword] = useState<string>('');
  const [confirmPassword, setConfirmPassword] = useState<string>('');
  const [validationMessage, setValidationMessage] = useState<string>('');

  const handleSignUp = () => {
    if (email === "" || password === "" || confirmPassword === "") {
      setValidationMessage('Please fill in the blank')
      return;
    };
    if (password !== confirmPassword) {
      setValidationMessage("password don't match");
      return;
    } else {
      setValidationMessage("");
    };

    try {
      createUserWithEmailAndPassword(auth, email, password)
        .then(userCredential => {
          console.log(userCredential.user.email);
          navigation.navigate('Login');
        })
    } catch (error) {
      if (error instanceof Error) {
        setValidationMessage(error.message);
      }
    };
  };

  const checkPassword = (password: string, confirmPassword: string) => {
    if (password !== confirmPassword) {
      setValidationMessage("password don't match");
    } else {
      setValidationMessage("");
    };
  };

  return (
    <View style={styles.container}>
      <View style={styles.inputContainer}>
        {<Text style={styles.error}>{validationMessage}</Text>}
        <TextInput
          placeholder='Email'
          value={email}
          onChangeText={text => setEmail(text)}
          style={styles.input}
        />
        <TextInput
          placeholder='Password'
          value={password}
          onChangeText={text => setPassword(text)}
          style={styles.input}
          secureTextEntry
        />
        <TextInput
          placeholder='Confirm password'
          value={confirmPassword}
          onChangeText={text => setConfirmPassword(text)}
          style={styles.input}
          secureTextEntry
          onBlur={() => checkPassword(password, confirmPassword)}
        />
      </View>

      <View style={styles.buttonContainer}>
        <Text>Create a new account</Text>
        <TouchableOpacity
          onPress={handleSignUp}
          style={[styles.button, styles.buttonOutline]}
        >
          <Text style={styles.buttonOutlineText}>Sign Up</Text>
        </TouchableOpacity>
      </View>
    </View>
  )
}

以上がログインとサインアップです. 次回はホーム画面にログアウトを追加します.