Android
Firebase

Railsのコードを書けないAndroidアプリ開発者がFirebaseを使ってチャットアプリを作る

More than 3 years have passed since last update.

昨晩のGoogle IO 2016で、Firebaseの大幅機能拡充が発表されました。

Railsのコードを書けないAndroidアプリ開発者がnifty cloud mobile backendを使ってチャットアプリを作る っていうのをやったときに、ニフティクラウド モバイルバックエンド最大の欠点であった、「リアルタイムDBが使えない!」っていうのがFirebaseではいけてるように見えたので、実際にどうなのかさわってみることにしました。


アプリケーションの作成

image

なんかイイ感じのページから「GET STARTED FOR FREE」で

image

アプリケーションを新規作成。


アプリとFirebaseのひも付け

image

Googleログインを利用してラクしたいので、SHA-1ハッシュを登録します。

まずは、Android StudioでKeyStoreをつくります。

image

image


SHA-1

$ keytool -exportcert -list -v -alias fuga -keystore fugafuga.jks 

キーストアのパスワードを入力してください:
別名: fuga
作成日: 2016/05/19
エントリ・タイプ: PrivateKeyEntry
証明書チェーンの長さ: 1
証明書[1]:
所有者: CN=Yusuke Iwaki, OU=Development, O=CrowdWorks, L=Shibuya, ST=Tokyo, C=JP
発行者: CN=Yusuke Iwaki, OU=Development, O=CrowdWorks, L=Shibuya, ST=Tokyo, C=JP
シリアル番号: 12df6f13
有効期間の開始日: Thu May 19 12:25:23 JST 2016終了日: Mon May 13 12:25:23 JST 2041
証明書のフィンガプリント:
MD5: C3:BC:08:68:E1******ひみつ******:0F:00:7B
SHA1: 4B:15:15:A8:F3******ひみつ******:0B:6C:84:A7
SHA256: 8C:36:D2:C1:35******ひみつ******:9F:86:80
署名アルゴリズム名: SHA256withRSA
バージョン: 3

拡張:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 01 DE E2******ひみつ******8.=z .P.>
0010: DF 62******ひみつ******
]
]


SHA1のところをFirebaseにいれます。

image

びっくりするくらい丁寧な説明がでますw


アプリにFirebaseを組み込む

https://firebase.google.com/docs/android/setup#add_the_sdk にあるとおりですが、今回は


  • firebase-core

  • firebase-database

  • firebase-auth

の3つを組み込みます。


組み込み

diff --git a/app/build.gradle b/app/build.gradle

index 1e130c6..097e3b1 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -23,4 +23,10 @@ dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0'
-}
\ No newline at end of file
+
+ compile 'com.google.firebase:firebase-core:9.0.0'
+ compile 'com.google.firebase:firebase-database:9.0.0'
+ compile 'com.google.firebase:firebase-auth:9.0.0'
+ compile 'com.google.android.gms:play-services-auth:9.0.0'
+}
+apply plugin: 'com.google.gms.google-services'
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 58f1f1b..fa5c600 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,7 @@ buildscript {

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
+ classpath 'com.google.gms:google-services:3.0.0'
}
}



ログイン周りをつくる

以前に、ニフティクラウドのモバイルバックエンドのテストアプリ作った時のやつ を流用します。

Google OAuthやるのがやっぱり面倒になってきたので(え?w)、ID/passで新規会員登録・ログインを実装します。

image

とりあえずFirebaseがわでEmail認証をONにします。

前回つくったやつを流用して、会員登録/ログイン/ログアウトをすごく雑につくると・・・

image

で登録すると、次の瞬間に、Firebaseのコンソールにユーザが現れました!

Bitmap.png

このあたりはニフティクラウドとほぼ同等の使用感。

ただ、細かいことを言うと、会員登録のコールバックをPromise文法で書けるあたりはさすが。ニフティクラウドよりもイケてる。


ログインのコード例

FirebaseAuth.getInstance().signInWithEmailAndPassword(email, password).continueWith(new Continuation<AuthResult, Object>() {

@Override
public Object then(@NonNull Task<AuthResult> task) throws Exception {
if (!task.isSuccessful()) {
Log.e("FugaFugaWorks", "error", task.getException());
}
return null;
}
});


メッセージの送受信を作る

いよいよお楽しみのRealtime DBですね。

Meteor使いもびっくりの、オブジェクトDB。詳細はこのへんの記事がわかりやすいです。

データベースに突っ込むのも引っ張ってくるのも、結構ゆるい感じです


モデルを定義


Message

public class Message {

public String author;
public String content;

public Message(String author, String content) {
this.author = author;
this.content = content;
}
}


POJOなかんじで。てきとうです。


メッセージ送信(DBにデータをつっこむ)


DBにつっこむ

    private DatabaseReference getMessageRef() {

FirebaseDatabase database = FirebaseDatabase.getInstance();
return database.getReference(MESSAGE_STORE); // MESSAGE_STORE = "message"
}

private void sendMessage(String content) {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();

getMessageRef().push().setValue(new Message(user.getUid(), content)).continueWith(new Continuation<Void, Object>() {
@Override
public Object then(@NonNull Task<Void> task) throws Exception {
if (!task.isSuccessful()) {
Log.e("FugaFugaWorks","error", task.getException());
return null;
}

((TextView) findViewById(R.id.txt_content)).setText("");
return null;
}
});
}


ポイントは、書いたあとに特にDBのリロードとかはやっていないということ。なぜなら、リアルタイムDBの恩恵により、DBに突っ込まれた次の瞬間に変更通知が降ってきて、ビューが更新されるから。


メッセージ表示(DBからロード)

「ロード」と言ってしまうとワンショットで取ってくるイメージが強いですが、Firebaseの考え方としては、おそらく「DBのなかのデータモデルをビューに写像するだけ」というものです。

firebase.png

どうやってリスト表示しようかなーめんどくさいなーと悩んでいたところ、Firebase-uiというサブプロジェクトが、Firebaseをリスト表示してくれるアダプタを提供しているじゃありませんか!

ありがたく拝借。


ListAdapter

        mAdapter = new FirebaseListAdapter<Message>(this, Message.class, android.R.layout.simple_list_item_1, getMessageRef()) {

@Override
protected void populateView(View v, Message model, int position) {
((TextView) v).setText(model.author+": "+model.content);
}
};
ListView listview = (ListView) findViewById(R.id.listview);
listview.setAdapter(mAdapter);

CRUDの世話を全くしなくていいのが本当に素晴らしい。


実際にメッセージを送ってみる

Bitmap.png

すると即座に(しかもリアルタイムに!)FirebaseのWebコンソールに反映されて↓

image

さらに次の瞬間には・・・

image

画面にも反映される、という。


まとめ

すっごい簡単にチャットアプリがつくれました。

たぶんGCM(あらためFCM?)とか使うとプッシュ通知も簡単に届くんだと思います。

test.gif

リアルタイムDBさわってみて、Meteorを初めて見た時のような感動で、結構しびれました。


(というか・・・

https://github.com/firebase/AndroidChat

サンプルあるやーん!!ww