React Native+firebaseで自動ログイン機能を作る

最近では、最速でサービスをリリースするのであれば、React Native+firebaseが最強という声も上がり始めています。

しかし、気軽に試してみようにもいかんせんドキュメントは少ないですし、どこから始めていいのやら?という感じですよね。

今回は、どのようなサービスを作るにも欠かせない自動ログイン機能をReact Native+firebaseで実装してみます。

React Nativeとは

その前に簡単にReact Nativeとfirebaseの説明をしておきます。

React Nativeとは、facebookがオープンソースで提供しているJavaScriptのフレームワークです。

最大の特徴としては、なんといってもiOSとAndroidの両方を一つのソースで開発することができることです。

つまり、従来のようにiOSならばSwift、AndroidならばKotolinといったように別でソースコードを用意する必要がありません。

JavaScript(というかJSX)で動作するので、学習コストが比較的小さいというのも特徴でしょう。

firebaseとは

firebaseとは、Googleが提供しているMBaaSです。

簡単に言ってしまうとバックエンド側で必要な機能を一通り全て提供してくれてるサービスです。

サーバのセットアップやメンテナンスなどはもちろん、auth認証やスマホのpush通知といったアプリに必要な機能もついています。

オンラインでサインアップするだけで、これらの機能が全て使えるので非常に開発スケジュールを短縮することができるというわけなのです。

今回は、firebaseを使って自動ログインを実装するためにreact-native-firebaseというsdkを使います。

自動ログインは、react-native-firebaseを使わなくても実装できるのですが、auth認証だけでなく、storageやDB、push通知などあらゆるサービスを提供してくれており、汎用性が高いので今回はreact-native-firebaseを使うことを考えて進めていきます。

React Nativeのアプリを作成する

では、実際にauth認証をするためのアプリを作成していきましょう。

環境としては、Nodejsがインストールされている前提で進めていきます。

公式に書いてある通り、まずは下記コマンドで制作するアプリを作ってみます。

$ npm install -g create-react-native-app
$ create-react-native-app firebaseAuth
$ cd firebaseAuth

ただ、create-react-native-appで作成したアプリは、Android StudioとXcodeを必要とせず開発できるもののネイティブコード、つまりSwiftやJavaなどのライブラリをコンパイルすることができません。

react-native-firebaseを利用するために、これをejectします。

$ npm run eject

これで、新しいReact Nativeのアプリを制作できました。ついでにreact-native-firebaseのライブラリも追加しておきましょう。

$ npm install --save react-native-firebase

続いて、ログインの認証機能のためにfirebaseを利用するので、firebaseにアプリを登録します。

firebaseにアプリを登録する

firebaseの公式ページに行きます。

そして右上のコンソールへ移動というボタンを押し、プロジェクト作成画面に行きます。

プロジェクトを追加というボタンをクリックすると下記の画面が出てくるので、適当にプロジェクト名を入力して国/地域を日本に設定しておきましょう。

そうするとプロジェクトの画面に移動することができます。

今回はiOSで自動ログイン機能を実装することを考えるので、iOSアプリにFirebaseを追加をクリックして下記の画面が表示されることを確認します。

iOSのバンドルIDの登録を求められるので、作成アプリのバンドルIDを確認しましょう。

バンドルIDの確認方法は firebaseAuth/ios/firebaseAuth.xcodeprj をxcodeで開きます。

firebaseAuth.xcodeprjを開くとIdentify → Bundle Identifier からバンドルIDを確認することができます。

このバンドルIDを入力してアプリを登録を押すと、GoogleService-info.plistをダウンロードできるようになります。

これを記載通り、Xcodeプロジェクトのルートに配置します。

アプリにFirebaseの設定を加える

アプリにFirebaseの初期化を行うため、ios/fiebaseAuth/AppDelegate.mに #import <Firebase.h> と [FIRApp configure]; を下記のように設定します。

続いてFirebaseのライブラリを読み込ませるためにCocoapodsを使用します。Cocoapodsがインストールされてない場合はここなどでインストールを済ませておいてください。

cd firebaseAuth/ios/
pod init

上記コマンドでCocoapodsのファイルを初期化した上で、Podfileを下記のように編集します。

platform :ios, '9.0'
target 'firebaseAuth' do
  pod 'Firebase/Core', '~> 5.3.0'
end

上記のようにPodfileを変更したら、pod install でFirebaseのライブラリをアプリに読み込ませます。また、react-native-firebaseにもこれらをリンクします。

pod install
cd ..
react-native link react-native-firebase

これで事前準備は完了です。一応ここまで上手く手順が進められているか確認してみましょう。

firebaseAuth/App.jsを下記のように編集してみます。

import React from "react";
import { StyleSheet, Text, View } from "react-native";
import firebase from "react-native-firebase";

export default class App extends React.Component {
  render() {
    console.log(firebase);
    return (
      <View style={styles.container}>
        <Text>Open up App.js to start working on your app!</Text>
        <Text>Changes you make will automatically reload.</Text>
        <Text>Shake your phone to open the developer menu.</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center"
  }
});

ここでは、3行目にreact-native-firebaseのライブラリを追加したのと、7行目にimportしたライブラリを表示しています。

cocoapodsを利用しているので、firebaseAuth/ios/firebaseAuth.xcworkspace をxcodeで開き、実行してみましょう。

このように実行してもエラーが発生されず、firebaseの中身が表示されると正しく動作できています。

続いていよいよ自動ログインの実装に入っていきます。

Firebase/Authのインストール

自動ログインにあたってreact-native-firebaseのauth機能を利用します。

そのため、firebaseAuth/ios/Podfileを下記のようにしてauth機能を追加します。

platform :ios, '9.0'
target 'firebaseAuth' do
  pod 'Firebase/Core', '~> 5.3.0'
  pod 'Firebase/Auth', '~> 5.3.0'
end

そして追加したpod updateを実行してライブラリを読みこみましょう。

cd ./ios
pod update

必ず動作確認をする際には再度ビルドし直してから実行してみてください。

レイアウトの実装

いよいよ終盤です。それでは、実際に自動ログインを実装してみましょう。

まずはスクリーンのページネーションを実装します。完成図としては、ログインがされていないときにはログイン画面が表示され、ログインがされているときにはログイン完了画面が表示されるようにします。

ページネーションを実装するためreact-navigationというライブラリをインストールします。

cd ..
npm install --save react-navigation

そして、ログイン画面とログイン完了画面のページを用意します。

mkdir screen
touch screen/LoginView.js screen/CompleteLogin.js

ページネーションについてはこちらのページを見てもらうとして省略します。

下記のようにレイアウトの調整だけ先にしておきます。
firebaseAuth/App.js

import { createStackNavigator } from "react-navigation";
import LoginViewScreen from "./screen/LoginView";
import CompleteLoginScreen from "./screen/CompleteLogin";

export default createStackNavigator(
  {
    LoginView: {
      screen: LoginViewScreen
    },
    CompleteLogin: {
      screen: CompleteLoginScreen
    }
  },
  {
    initialRouteName: "LoginView"
  }
);

firebaseAuth/screen/LoginView.js

import React from "react";
import { Text, View, TextInput, Button, StyleSheet } from "react-native";

export default class LoginView extends React.Component {
  state = {
    email: "",
    password: ""
  };
  onPress = () => {};
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.title}>Sign up</Text>
        <TextInput
          style={styles.input}
          onChangeText={email => this.setState({ email })}
          value={this.state.email}
        />
        <TextInput
          style={styles.input}
          onChangeText={password => this.setState({ password })}
          value={this.state.password}
        />
        <Button title="Sign up!!" onPress={this.onPress()} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center"
  },
  title: {
    fontSize: 32,
    fontWeight: "bold"
  },
  input: {
    height: 30,
    width: 300,
    marginVertical: 15,
    borderWidth: 1
  }
});

firebaseAuth/screen/CompleteLogin.js

import React from "react";
import { Text, View, StyleSheet } from "react-native";

export default class CompleteLogin extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.text}>Login Successful!!</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center"
  },
  text: {
    fontSize: 32,
    fontWeight: "bold"
  }
});

上記の状態だと下記画像のように表示されるはずです。

自動ログインの実装

それではいよいよ自動ログインの実装に入っていきましょう。

自動ログインを実装するためには、
・ ログイン機能の実装
・ ログイン状態の保持
をする必要があります。

1つ目の機能としてはfirebaseが提供してくれており、先程それを使用するためのAuthライブラリもインストールしています。便利なものですね!

そして2つ目のログイン状態の保持は、端末のローカルストレージにログインしているかどうかを保持します。こちらはReact NativeのAsyncStorageという端末のローカルストレージを利用できるメソッドを利用します。

まず、事前準備としてfirebase上においてメールアドレスとパスワードでログインを行うために、Authentication → ログイン方法 から画像のようにメール、パスワードのステータスを有効にしておきます。

今回の作成する自動ログインのプログラムとしては、
・ メールアドレスとパスワードを入力して登録ボタンを押せばアカウントが登録され、ログインされる
・ 2度目からは自動的にログイン処理が行われる
というプログラムを作成していきます。

したがって、ログインされているかどうかチェックするための処理をcomponentDidMount()に、実際に登録をする処理をボタンがonPressされた場合に書き加えていきます。

今回編集するファイルは、firebaseAuth/screen/LoginView.js のみで、最終的なコードは下記のようになります。

import React from "react";
import {
  Text,
  View,
  TextInput,
  Button,
  StyleSheet,
  AsyncStorage
} from "react-native";
import firebase from "react-native-firebase";

export default class LoginView extends React.Component {
  state = {
    email: "",
    password: ""
  };
  async componentDidMount() {
    const isLogin = await AsyncStorage.getItem("isLogin");
    isLogin
      ? this.props.navigation.replace("CompleteLogin")
      : console.log("false");
  }
  onPress = async () => {
    try {
      await firebase
        .auth()
        .createUserAndRetrieveDataWithEmailAndPassword(
          this.state.email,
          this.state.password
        );
      await AsyncStorage.setItem("isLogin", "true");
      this.props.navigation.replace("CompleteLogin");
    } catch (e) {
      // エラー処理
      console.log(e);
    }
  };
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.title}>Sign up</Text>
        <TextInput
          style={styles.input}
          onChangeText={email => this.setState({ email })}
          value={this.state.email}
        />
        <TextInput
          style={styles.input}
          onChangeText={password => this.setState({ password })}
          value={this.state.password}
        />
        <Button title="Sign up!!" onPress={() => this.onPress()} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center"
  },
  title: {
    fontSize: 32,
    fontWeight: "bold"
  },
  input: {
    height: 30,
    width: 300,
    marginVertical: 15,
    borderWidth: 1
  }
});

簡単に説明するとボタンが押された際にはfirebaseのauth機能のうちのcreateUserAndRetrieveDataWithEmailAndPassword()というメソッドを使ってユーザー登録を行っています。

そしてユーザー登録が完了すると、ローカルストレージにisLoginというkeyに”true”という文字列を登録しています。

2度目からはcomponentDidMount()の段階でisLoginに文字列がセットされているので、自動的にログインができるというわけなのです。

細かい画面遷移やキャッシュ、ユーザー登録のバリデーションなどについては様々な修正が必要ですが、大きくはこれで自動ログインが実装できたと言えるでしょう。

完成したソースをgithubで公開しているので、もしよければ見てください。
https://github.com/kawasaki-t0325/auto-login

まとめ

今回は、React Native + firebaseを使って自動ログインを実装する方法について紹介しました。

上記でもお話していますが、まだまだ上記の自動ログインは改良の余地が有り余るほどあります。

ただ、基本的にはこちらで自動ログインができるので、ぜひ参考になれば幸いです。

SNSでもご購読できます。

コメントを残す

*