Slide 1

Slide 1 text

FirebaseとReact Nativeでの モバイルアプリの作り方 DevFest Tokyo 2017 @k2wanko

Slide 2

Slide 2 text

コキチーズ @k2wanko セキュリティエンジニア GCPUG staff FirebaseとGoogle App Engineと 鮨と肉とドン勝が好き

Slide 3

Slide 3 text

今日話すこと - Firebaseとは何か - React Nativeについて - Firebaseの各種サービスとReact Native Firebaseについて このセッションで得られないもの - アプリを0から作る方法 - アプリを運用していく知見 - Reactの書き方

Slide 4

Slide 4 text

Firebaseとは?

Slide 5

Slide 5 text

モバイルアプリ向けのmBaaS

Slide 6

Slide 6 text

認証やオンラインでのデータの保存ができる。

Slide 7

Slide 7 text

Googleが買収してGCPに統合された

Slide 8

Slide 8 text

FirebaseはただのBaaSではない Develop Grow EARN

Slide 9

Slide 9 text

FirebaseはただのBaaSではない Develop Grow EARN Analytics

Slide 10

Slide 10 text

コキチーズの得意なこと Grow EARN Analytics Develop

Slide 11

Slide 11 text

なぜFirebaseを使うのか?

Slide 12

Slide 12 text

クライアントを作ることに集中したい - 作るものの本質に集中したい - MySQLを用意したりサーバー台数を考えたりしたくない

Slide 13

Slide 13 text

サーバーを管理する必要がない - SSHしたくない - apt-getもyumもしたくない

Slide 14

Slide 14 text

料金が安い - Googleのインフラに乗ってる部分は安い - 個人開発ではとりあえず作って試して放置しててもお金がかからない - 試しに作ったサービスをスケールさせることも容易 (ベストプラクティスに従って作っていれば)

Slide 15

Slide 15 text

React Nativeとは?

Slide 16

Slide 16 text

React でモバイルアプリが作れるやつ

Slide 17

Slide 17 text

NativeのViewをJSXで書ける

Slide 18

Slide 18 text

WebViewではない JavaScriptCore

Slide 19

Slide 19 text

ブラウザの機能もいくつかサポートしてる - Fetch - WebSocket - setTimeout - setInterval - など

Slide 20

Slide 20 text

JavaScriptな部分はいつでもアップデートできる

Slide 21

Slide 21 text

他にも - ネイティブモジュールでネイティブの機能にアクセスもできる - クロスプラットフォームでロジックやデザインの共通化 - ロジックをJSで書くことでテストもエミュレータを必要としない - 全てをReact Nativeで書かずに部分的にReact Nativeにすることも可能

Slide 22

Slide 22 text

React Nativeでよく使われるライブラリ

Slide 23

Slide 23 text

NativeBase - React Native用の デザインフレームワーク - Android/iOSで プラットフォームに 合わせたデザインが作れる

Slide 24

Slide 24 text

react-navigation - React Native用の ルーティングライブラリ - タブ、スタック、ドロワーに 対応している

Slide 25

Slide 25 text

MobX - Reactで データバインディングを 実現するライブラリ - Reactだとステート管理はRedux が主流だけど Vue.jsみたいに書きたいので MobX便利

Slide 26

Slide 26 text

React Native Firebase - サードパーティ製 React Native用 Firebase SDK - 公式のWebSDKでは使えない サービスもJavaScriptで書ける

Slide 27

Slide 27 text

Firebase x React Native

Slide 28

Slide 28 text

Firebase Authentication - ユーザー認証を実装できるサービス - Twitter,Google,Facebook,GitHubに対応 - メール認証やSMS認証、匿名認証もサポート - LINEなどサポートされていないプロバイダの認証には カスタム認証で自前でトークンを作って認証もできる。 - カスタム認証はプレミアムユーザーとか管理者権限を付けるとかにも使う

Slide 29

Slide 29 text

firebase.auth().signInWithEmailAndPassword('[email protected]', '123456') .then((user) => { console.log('User successfully logged in', user) }) .catch((err) => { console.error('User signin error', err); });

Slide 30

Slide 30 text

componentDidMount() { this.unsubscribe = firebase.auth().onAuthStateChanged((user) => { if (user) { // User is signed in. } }); } componentWillUnmount() { if (this.unsubscribe) { this.unsubscribe(); } }

Slide 31

Slide 31 text

Realtime Database - オンラインでもオフラインでもデータが保存できて リアルタイムに同期が可能なKVSのデータベース - クライアントからSDKを通して直接データベースに書き込める - ユーザーデータの保護にはセキュリティルールで読み書きに制限をつけれる

Slide 32

Slide 32 text

データの読み込み firebase.database() .ref('posts') .on('value', (snapshot) => { const value = snapshot.val(); });

Slide 33

Slide 33 text

データの書き込み firebase.database() .ref('posts/1234') .set({ title: 'My awesome post', content: 'Some awesome content', });

Slide 34

Slide 34 text

// On mount, subscribe to ref updates componentDidMount() { this.ref = firebase.database().ref('posts/1234'); this.ref.on('value', this.handlePostUpdate); } // On unmount, ensure we no longer listen for updates componentWillUnmount() { if (this.ref) { this.ref.off('value', this.handlePostUpdate); } } // Bind the method only once to keep the same reference handlePostUpdate = (snapshot) => { console.log('Post Content', snapshot.val()); }

Slide 35

Slide 35 text

Google Analytics for Firebase - モバイル版Google Analytics - ユーザーの行動をトラッキングできる

Slide 36

Slide 36 text

カスタムイベント firebase.analytics().logEvent('clicked_advert', { id: 1337 }); 任意のイベントを記録できる firebase.analytics().setCurrentScreen('user_profile'); 現在のスクリーンを指定できる

Slide 37

Slide 37 text

ユーザープロパティ firebase.analytics().setUserId(id); ユーザーIDの設定 firebase.analytics().setUserProperty('nickname', 'foobar'); その他のプロパティを設定

Slide 38

Slide 38 text

Firebase Cloud Messaging - Push通知を送るためのサービス - SDKを通してPush用のトークンを取得できる - トピック機能がありそのトピックを参照しているユーザのみに通知する こともできる

Slide 39

Slide 39 text

トークンの取得方法 firebase.messaging().getToken() .then((token) => { console.log('Device FCM Token: ', token); }); firebase.messaging().onTokenRefresh((token) => { console.log('Refreshed FCM token: ', token); });

Slide 40

Slide 40 text

Notificationをクリックして受け取る場合 firebase.messaging().getInitialNotification() .then((notification) => { console.log('notification:', notification); });

Slide 41

Slide 41 text

No content

Slide 42

Slide 42 text

アプリが起動中に受け取る場合 firebase.messaging().onMessage((message) => { console.log('onMessage', message); });

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

注意点 - getInitialNotificationとonMessageで受け取れる結果が違う(Android) - iOSではPermissionを求める必要がある。 - Notificationのカスタマイズはドキュメントにない - カスタマイズしようと思ったら頑張りが必要そう

Slide 45

Slide 45 text

Cloud Storage for Firebase - 画像や動画など大きめのファイルを保存するためのストレージ - SDKを通してクライアントから直接書き込める - データの保護にはセキュリティルールがあるので安心

Slide 46

Slide 46 text

const unsubscribe = firebase.storage() .ref('/files/1234') .putFile('/path/to/file/1234') .on('state_changed', snapshot => { //Current upload state }, err => { //Error unsubscribe(); }, uploadedFile => { //Success unsubscribe(); });

Slide 47

Slide 47 text

Firebase Remote Config - アプリケーションの設定ファイルを共有できるサービス - アナリティクスを元にユーザーごとに設定を切り替えられる

Slide 48

Slide 48 text

開発者モード firebase.config().enableDeveloperMode();

Slide 49

Slide 49 text

firebase.config().fetch() .then(() => { return firebase.config().activateFetched(); }) .then((activated) => { if (!activated) console.log('Fetched data not activated'); return firebase.config().getValue('hasExperimentalFeature'); }) .then((snapshot) => { const hasExperimentalFeature = snapshot.val(); if(hasExperimentalFeature) { // enableSuperCoolFeature(); } // continue booting app }) .catch(console.error);

Slide 50

Slide 50 text

Firebase Crash Reporting - クラッシュした時のデータを集めてくれるサービス - もう少ししたらCrashlyticsがメインのクラッシュレポートサービスになる - React Native Fabric経由でCrashlyticsを使おう! - https://github.com/corymsmith/react-native-fabric

Slide 51

Slide 51 text

AdMob - アプリに広告を載せるためのサービス - 収益はGoogle Analytics for Firebaseでも確認できる

Slide 52

Slide 52 text

バナー広告 const Banner = firebase.admob.Banner const ad = () => { return ( { console.log('Advert loaded and is now visible'); }} onAdFailedToLoad={(err) => { console.warn('onAdFailedToLoad', err) }} > ) }

Slide 53

Slide 53 text

Cloud Functions for Firebase - イベント駆動でNode.jsを実行できるサービス - RealtimeDatabseの書き込みやユーザーの作成、削除をトリガーに実行 - 今までできなかったことが可能になる - 不適切なメッセージの削除 - ユーザー削除時に関連データの削除 - アナリティクスのイベントを元に Push通知 - REST APIやWebHookの受取

Slide 54

Slide 54 text

ユーザー作成時にメールを送る関数 const functions = require('firebase-functions'); exports.sendWelcomeEmail = functions.auth .user().onCreate(event => { // ... });

Slide 55

Slide 55 text

Cloud Firestore (beta) - RealtimeDatabaseの後継データベース - ドキュメント指向のデータベース - Realtime Databaseより高度なQueryとTransaction処理が可能 - React Native Firebase v3.0.0から対応してる

Slide 56

Slide 56 text

Firestoreの概念

Slide 57

Slide 57 text

コレクションの取得 firebase.firestore() .collection('posts') .get() .then(querySnapshot => { // Access all the documents in the collection const docs = querySnapshot.docs; // Access the list of document changes for the collection const changes = querySnapshot.docChanges; // Loop through the documents querySnapshot.forEach((doc) => { const value = doc.data(); }) })

Slide 58

Slide 58 text

フィルターと並べ替え citiesRef.where("population", ">", 100000).orderBy("population") Realtime Databaseだとアプリ側でソートや降順処理が必要だったが Firestoreではクエリーで対応可能

Slide 59

Slide 59 text

ドキュメントの追加 firebase.firestore() .collection('posts') .add({ title: 'Amazing post', }) .then(() => { // Document added to collection and ID generated // Will have path: `posts/{generatedId}` })

Slide 60

Slide 60 text

ドキュメントの更新 var washingtonRef = firebase.firestore().collection("cities").doc("DC"); // Set the "capital" field of the city 'DC' return washingtonRef.update({ capital: true }) .then(function() { console.log("Document successfully updated!"); }) .catch(function(error) { // The document probably doesn't exist. console.error("Error updating document: ", error); });

Slide 61

Slide 61 text

ドキュメントの更新検知 var unsubscribe = firebase.firestore().collection("cities").doc("SF") .onSnapshot(function(doc) { console.log("Current data: ", doc && doc.data()); }); unsubscribe();

Slide 62

Slide 62 text

特定のフィールドの削除 var cityRef = firebase.firestore().collection('cities').doc('BJ'); // Remove the 'capital' field from the document var removeCapital = cityRef.update({ capital: firebase.firestore.FieldValue.delete() });

Slide 63

Slide 63 text

FirestoreとRealtime Databaseの違い Firestore - ドキュメント指向 - 複合Indexで条件フィルタリング可能 - AtomicなBatch処置とTransaction - beta - 自動的にスケール - ストレージ月1GB $0.18 Realtime Databse - 1つのJSON Tree - 限定的な並べ替えとlimit - 基本的なTransaction - GA - シャーディングによるスケール - ストレージ月 1GB $5

Slide 64

Slide 64 text

初心者がFirebaseについて見ておくと いい場所

Slide 65

Slide 65 text

https://gcpug.jp/join

Slide 66

Slide 66 text

まとめ Firebase が向いてる人 サーバの開発運用を最小限にしたい人 React Nativeが向いている人 JavaScriptが書けてネイティブも少し分かる人 Expo使えばJavaScript書ける人なら片手間でも行ける よくわからないことはGCPUGで聞くといいよ!

Slide 67

Slide 67 text

Q & A