React Native Router Fluxでタブの履歴を残す方法

InstagramのようにAndoridのバックボタンで前のタブに戻るようにするためにどのタブが前のタブか知る必要があります。React Native Router Flux(with Redux)を使っていて、これを実現するために下記のようなReducerを作りました。

const initialState = {
  scene: {},
  tabHistory: [],
};

export default function reducer(state = initialState, action = {}) {
  switch (action.type) {
    // focus action is dispatched when a new screen comes into focus
    case "focus":
      return {
        ...state,
        scene: action.scene,
      };

    case 'REACT_NATIVE_ROUTER_FLUX_FOCUS':   
      if(action.scene.name === "tabBar"){
        if(state.tabHistory.length === 0 || state.tabHistory[0] !== action.scene.children[action.scene.index].name){
          return {
            ...state,
            tabHistory: [action.scene.children[action.scene.index].name, ...state.tabHistory ].slice(0, 10)
          }
        }
      }

やってることは、FOCUSしたときにtabHistoryとして、Arrayに追加してるだけです。無限に履歴を残す必要はないので10個で制限してますが、もしかしたら2つでいいかもしれません(最初の要素は現在のタブになるので二つ以上は必要)

で、これを下記みたいな感じでBackAndroidで使用すれば良いでしょう。

  handleAndroidBack(){
    const tabHistory = store.getState().router.tabHistory;
    if(tabHistory.length > 1){ // 0 is the current tab
      const previousTab = tabHistory[1];
      switch(previousTab){
        case "feeds":
          Actions.feeds();
          return true;
        case "discussion":
          Actions.discussion();
          return true;
        case "profile":
          Actions.profile();
          return true;
        case "notification":
          Actions.notification();        
          return true;
        case "others":
          Actions.others();
          return true;
      }
    }
   return false;          
  }

[React Native] Androidエミュレーターでのデバッグ方法

CMD-mでデバッグwindow表示して、Debug JS remotelyをクリック。 でも、ものすごく遅いので、ターミナルから下記を走らせた方がいい。 (表示はChromeのデバッグほどきれいじゃないけど。。)

$ adb logcat *:S ReactNative:V ReactNativeJS:V

コマンドラインからAndroid Emulatorを起動する方法

React Nativeの人なので、どうやってEmulatorを起動するかわかりませんでした。React NativeのGet started(ver 0.38)を終わって、 Android Studioからは起動できることを確認しています

$ android list avd
*************************************************************************
The "android" command is deprecated.
For manual SDK, AVD, and project management, please use Android Studio.
For command-line tools, use tools/bin/sdkmanager and tools/bin/avdmanager
*************************************************************************
Running /Users/shohey1226/Library/Android/sdk/tools/bin/avdmanager list avd

Available Android Virtual Devices:
    Name: Nexus_5X_API_25
  Device: Nexus 5X (Google)
    Path: /Users/shohey1226/.android/avd/Nexus_5X_API_25.avd
  Target: Google APIs (Google Inc.)
          Based on: Android 7.1.1 (Nougat) Tag/ABI: google_apis/x86_64
    Skin: nexus_5x
  Sdcard: 100M
---------
    Name: Nexus_5X_API_25_x86_64
  Device: Nexus 5X (Google)
    Path: /Users/shohey1226/.android/avd/Nexus_5X_API_25_x86_64.avd
  Target: Google APIs (Google Inc.)
          Based on: Android 7.1.1 (Nougat) Tag/ABI: google_apis/x86_64
    Skin: nexus_5x
  Sdcard: 800M
Snapshot: no

$ emulator -avd Nexus_5X_API_25

上記コマンドできるはずですが、ライブラリのエラーがでて起動しません。

$ emulator -avd Nexus_5X_API_25
[140736266523584]:ERROR:./android/qt/qt_setup.cpp:28:Qt library not found at ../emulator/lib64/qt/lib
Could not launch '../emulator/qemu/darwin-x86_64/qemu-system-x86_64': No such file or directory

Stackoverflowを参考にして~/.bashrcにラップするfunctionを追加で無事エミュレーター起動しました。

# $HOME/.bashrc
function emulator { cd "$(dirname "$(which emulator)")" && ./emulator "$@"; }

React Native – Firebaseでユーザ作成を実装する

Google買収後、Firebaseのドキュメントもマテリアルデザインになりいい感じです。 Firebaseは、RNがでてきてすぐに対応したBaasの一つです。途中で、SDKが使えなくなり、古いバージョンで使うみたいなハックがあったように記憶しています。今は、問題なく動く(はず)です。

今回は、ちゃんと動くどうかを確かめる上でもユーザ作成あたりをさくっと実装してみます。

Firebaseのサイトに行き、アカウントを作成し、プロジェクトを作成して、”ウェブアプリにFirebaseを追加”をクリックしましょう。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-11-27-13-31-30

すると、下記のようなAPIキー情報もろもろが出てくるのでメモっておきます。

<script src="https://www.gstatic.com/firebasejs/3.6.1/firebase.js"></script>
<script>
  // Initialize Firebase
  var config = {
    apiKey: "YOURS",
    authDomain: "YOURS",
    databaseURL: "YOURS",
    storageBucket: "YOURS",
    messagingSenderId: "YOURS"
  };
  firebase.initializeApp(config);
</script>

忘れずにEmail認証をenableしておきましょう。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-11-27-13-46-03

React Nativeプロジェクトに追加するには、

1. Firebaseモジュールのインストール

$ yarn add firebase

早い噂のyarnを使ってますが、npm install firebase --saveと同義。

2. 初期化

この手の外部サービスは、app/utils/Firebase.jsのようにutils以下に入れるのが私の流儀です。

import * as firebase from 'firebase';

const config = {
  apiKey: "YOURS",
  authDomain: "YOURS",
  databaseURL: "YOURS",
  storageBucket: "YOURS",
  messagingSenderId: "YOURS"
};

module.exports = firebase.initializeApp(config);

3. 読み込んで使用する

今回は利用できるかのテストなので、componentDidMountにハードコードしてますが、ちゃんと使うにはテキストフィードを用意して、emailとパスワードを取得すれば良いと思います。

import firebase from './app/utils/Firebase';

export default class Kagami extends Component {

componentDidMount(){
let email = `test${new Date().getTime()}@test.com`;
let password = "hogehoge";

firebase.auth().createUserWithEmailAndPassword(email, password)
.catch(function(error) {
  // Handle Errors here.
  var errorCode = error.code;
  var errorMessage = error.message;
  if (errorCode == 'auth/weak-password') {
    alert('The password is too weak.');
  } else {
    alert(errorMessage);
  }
  console.log(error);
});
}

これをreloadすると、下記のようにユーザが作成されたのがわかると思います。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-11-27-13-44-23

Firebaseあっさり使えましたね。APIもParseと似ているので楽に使えそうです。