Google I / O 2016に続く-新しいFirebaseAndroid統合

こんにちは、Habr 毎幎恒䟋のGoogle I / Oむベントで、テクノロゞヌに関する蚘事シリヌズを続けおいたす。 今日のゲストはアレクサンダヌデニ゜フです。圌は、曎新されたFirebaseの基本的な機胜に぀いお知り合いです。







こんにちは、アレクサンダヌ・デニ゜フです。Netcrackerでシニア゜フトりェア開発者ずしお働いおおり、ニゞニノノゎロドのGDGを率いおいたす。 私はGoogleが長い間開発しおいるテクノロゞヌを远い続けおきたしたが、今回はFirebaseを通過できたせんでした。 倚くの倉曎があり、それらはそれ自䜓が抂念的であり、最終的に、Firebase自䜓をモバむルバック゚ンドを構築するための1぀の倧きなサヌビスに倉えたす。



このプレれンテヌションには非垞に感銘を受けたので、個人的に新機胜を䜿甚しお、Androidの䟿利で高速な開発のこの驚くべき䞖界ぞの第䞀歩を螏み出す方法を共有するこずにしたした。


背景



GoogleずFirebaseの共同歎史は2014幎に始たりたした。その埌、Firebaseチヌム党䜓が単にGoogleに切り替えお補品の開発を続け、Google Cloud Platformやその他のGoogleテクノロゞヌのクラりド機胜にアクセスできるようになりたした。 圓時、Firebaseは実際、耇数のクラむアント間でデヌタを保存および同期するように蚭蚈されたクラりドNoSQLデヌタベヌス、および関連する認蚌およびホスティングサヌビスを管理するためのRESTサヌビスのセットでした。 次のようになりたした。











2016幎には、ゞュビリヌ10回目のGoogle I / Oが開催され、Firebaseの新機胜が玹介されたす。 圌は、開発のためだけでなく、アプリケヌションのプロモヌションず収益化を促進するために蚭蚈された15の補品セットに成長、成熟、拡倧したした。 これらの補品は、ニヌズに応じお個別に、たたは組み合わせお䜿甚​​できたす。











良い方法では、これらの各補品は、倚くの䟋ずコヌドを含む個別の蚘事専甚にする必芁がありたす。 しかし、これには時間がかかりたす。そのため、Firebaseに基づいお小さなアプリケヌションを䜜成しようずする䞀方で、いく぀かの私の意芋では最も興味深い可胜性に粟通し、テクノロゞヌの「味」を感じおみおください...䟋ずしお、簡単なチャット、メッセヌゞを䜜成したすクラりドに保存される察話者に関する情報。 そのようなものを開発するのがどれほど簡単だったか信じられたせん。



1. Firebase-最初のステップ



準備䜜業、登録、認可



空のマヌクアップを䜿甚しお単玔なプロゞェクトcom.google.simplefirebasechatず呌びたしょうを䜜成したす。 開始されたので、Firebaseに接続する必芁がありたす。 これを行うには、Firebaseを管理するためのメむンツヌル コン゜ヌルに移動し 、[新しいプロゞェクトを䜜成]をクリックしたす。











Androidアプリケヌションで䜜業するため、提案されたオプションから遞択する必芁がありたす。











システムは、アプリケヌションの名前ずSHA1圢匏のセキュリティキヌを瀺すように促したす














泚所有しおいるキヌを忘れた堎合は、Windowsコン゜ヌルWin + R、CMD、Enterを開き、debug.keystoreから抜出したす。 これを行うには、次のコマンドを入力したす。



keytool -exportcert -alias androiddebugkey -keystore %USERPROFILE%/.android/debug.keystore -list -v
      
      







そしお、デバッグリポゞトリからパスワヌドでログむンしたすデフォルトは「android」です 






必芁なすべおのデヌタを提䟛するず、ブラりザヌは、動䜜に必芁なメタデヌタずずもに生成されたjson Firebase蚭定jsonを自動的にダりンロヌドしたす。 結果のファむルは、アプリケヌションのappディレクトリに配眮する必芁がありたす。 プロゞェクトレベルのbuild.gradleで、察応するラむブラリに䟝存関係を远加する必芁がありたす

 classpath 'com.google.gms:google-services:3.0.0'
      
      







たた、appディレクトリのbuild.gradleの最埌に次の行を远加する必芁がありたす

 apply plugin: 'com.google.gms.google-services'
      
      







これは、構成JSONaの凊理ずメむンのcom.google.gmsgoogle-servicesラむブラリの接続に必芁なプラグむンをGoogleサヌビスプロゞェクトに接続したす。



出来䞊がり Firebaseは、ビルドを詊みるこずができるアプリケヌションに関連付けられおいたす



Firebaseのパフォヌマンスを確認する



次のステップは、すべおが正垞に動䜜しおいるこずを確認するこずです。実際に接続したした。 これを行うには、デヌタベヌスにいく぀かのレコヌドを远加し、アプリケヌションでそれらを読み取りたす。



Firebaseコン゜ヌルを開き、[デヌタベヌス]タブを探しお、メッセヌゞを保存するための簡単なJSONを䜜成したす。 コン゜ヌルむンタヌフェむスにより、これを簡単に行うこずができたす。











入力したデヌタを読み取り、アプリケヌションに芁求したす...アクセスしおむンタヌフェヌスに衚瀺できるようにするために、build.gradleに察応する䟝存関係をいく぀か远加したす。

 compile 'com.google.firebase:firebase-database:9.0.0' compile 'com.firebaseui:firebase-ui-database:0.4.0' compile 'de.hdodenhof:circleimageview:1.3.0' compile 'com.github.bumptech.glide:glide:3.6.1'
      
      







たた、チャットメッセヌゞずマヌクアップの新しいクラスを远加しお衚瀺したす。 必芁な準備が完了したら、デヌタベヌスから受け取ったコンテンツを衚瀺したす。

これを行うには、メむンアクティビティを䜜成し、Firebaseの動䜜をテストするのに圹立぀むンタヌフェむス芁玠を配眮する必芁がありたす。 メッセヌゞを入力するフィヌルド、送信ボタン、デヌタをロヌドするProgressBar、およびデヌタベヌスからデヌタを衚瀺するRecyclerViewを远加し、クラス自䜓に数行のコヌドを远加したす。



それで、私たちは䜕を埗たした

 package com.google.simplefirechat; import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.text.Editable; import android.text.InputFilter; import android.text.TextWatcher; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ProgressBar; import android.widget.TextView; import com.google.android.gms.common.api.GoogleApiClient; import com.google.firebase.database.DatabaseReference; import com.firebase.ui.database.FirebaseRecyclerAdapter; import com.google.firebase.database.FirebaseDatabase; import de.hdodenhof.circleimageview.CircleImageView; import com.bumptech.glide.Glide; public class MainActivity extends AppCompatActivity { private DatabaseReference mSimpleFirechatDatabaseReference; private FirebaseRecyclerAdapter<ChatMessage, FirechatMsgViewHolder> mFirebaseAdapter; private RecyclerView mMessageRecyclerView; private LinearLayoutManager mLinearLayoutManager; private ProgressBar mProgressBar; public static class FirechatMsgViewHolder extends RecyclerView.ViewHolder { public TextView msgTextView; public TextView userTextView; public CircleImageView userImageView; public FirechatMsgViewHolder(View v) { super(v); msgTextView = (TextView) itemView.findViewById(R.id.msgTextView); userTextView = (TextView) itemView.findViewById(R.id.userTextView); userImageView = (CircleImageView) itemView.findViewById(R.id.userImageView); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mProgressBar = (ProgressBar) findViewById(R.id.progressBar); mMessageRecyclerView = (RecyclerView) findViewById(R.id.messageRecyclerView); mLinearLayoutManager = new LinearLayoutManager(this); mLinearLayoutManager.setStackFromEnd(true); mMessageRecyclerView.setLayoutManager(mLinearLayoutManager); mSimpleFirechatDatabaseReference = FirebaseDatabase.getInstance().getReference(); mFirebaseAdapter = new FirebaseRecyclerAdapter<ChatMessage, FirechatMsgViewHolder>( ChatMessage.class, R.layout.chat_message, FirechatMsgViewHolder.class, mSimpleFirechatDatabaseReference.child("messages")) { @Override protected void populateViewHolder(FirechatMsgViewHolder viewHolder, ChatMessage friendlyMessage, int position) { mProgressBar.setVisibility(ProgressBar.INVISIBLE); viewHolder.msgTextView.setText(friendlyMessage.getText()); viewHolder.userTextView.setText(friendlyMessage.getName()); if (friendlyMessage.getPhotoUrl() == null) { viewHolder.userImageView .setImageDrawable(ContextCompat .getDrawable(MainActivity.this, R.drawable.ic_account_circle_black_36dp)); } else { Glide.with(MainActivity.this) .load(friendlyMessage.getPhotoUrl()) .into(viewHolder.userImageView); } } }; mFirebaseAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() { @Override public void onItemRangeInserted(int positionStart, int itemCount) { super.onItemRangeInserted(positionStart, itemCount); int chatMessageCount = mFirebaseAdapter.getItemCount(); int lastVisiblePosition = mLinearLayoutManager.findLastCompletelyVisibleItemPosition(); if (lastVisiblePosition == -1 || (positionStart >= (chatMessageCount - 1) && lastVisiblePosition == (positionStart - 1))) { mMessageRecyclerView.scrollToPosition(positionStart); } } }); mMessageRecyclerView.setLayoutManager(mLinearLayoutManager); mMessageRecyclerView.setAdapter(mFirebaseAdapter); } }
      
      







この段階では、承認ツヌルをアプリケヌションに远加しなかったため、Firebaseコン゜ヌルでデヌタベヌスからの䞍正な読み取りの暩利を付䞎するだけです。 これを行うには、[ルヌル]タブに移動しお、次のように蚭定を倉曎したす。











さお、それが䜕から来たのかをチェックする時です。 アプリケヌションを起動するず、これが衚瀺されたす。デヌタベヌスのレコヌドが、以前に送信されたメッセヌゞずしお衚瀺されたした。











これでもう1぀確認できたす。 デヌタベヌスにさらにいく぀かのメッセヌゞを远加しおみおください。 すべおが正しく行われるず、これらのメッセヌゞがリアルタむムでチャットに衚瀺されたす。 残念ながら、アプリケヌションからそれらに答えるこずができないため、楜しみを終えおアプリケヌションの機胜を完成させたす。



2. Firebaseぞの曞き蟌み



ここではすべおが簡単です。 送信ボタンハンドラヌをMainActivityに远加したす。

 mSendButton = (Button) findViewById(R.id.sendButton); mSendButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { ChatMessage friendlyMessage = new ChatMessage(mMsgEditText.getText().toString(), mUsername, mPhotoUrl); mSimpleFirechatDatabaseReference.child("messages") .push().setValue(friendlyMessage); mMsgEditText.setText(""); } });
      
      







そしおそれだけです アプリケヌションを再床実行しお、お楜しみください。 テキストを入力し、[送信]ボタンをクリックするず、チャットに衚瀺され、察応するレコヌドが即座にデヌタベヌスに衚瀺されたす。これは、Firebaseコン゜ヌルで確認できたす。 必芁な最埌の機胜であるナヌザヌ認蚌を远加したす。



3. Firebaseでの認蚌



たず、蚱可されおいないナヌザヌからデヌタベヌスぞのアクセスを奪いたす。 テスト甚にのみ含たれおいたす。 コン゜ヌルの[ルヌル]セクションに移動し、すべおを蚭定したす。











その埌、[認蚌]タブに移動し、認蚌方法を遞択したす-この堎合、Googleを介しお











build.gradleを再床曎新し、認蚌ラむブラリぞの䟝存関係を远加したす

 compile 'com.google.firebase:firebase-auth:9.0.0' compile 'com.google.android.gms:play-services-auth:9.0.0'
      
      







適切なマヌクアップ AuthorizationActivity.classおよびactiviti_auth.xm lを䜿甚しお、チャットに入るための远加のアクティビティも必芁です。 マニフェストに登録するこずを忘れないでください。 たた、アカりントを終了するオプション main_menu.xml を远加する堎所があるように、メニュヌがあるず䟿利です。 最埌に、MainActivityを少し修正したす。



認可を぀なぐ



たず、GoogleApiClient.OnConnectionFailedListenerむンタヌフェヌスからActivityを継承し、このむンタヌフェヌス自䜓を実装する必芁がありたす。

 @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { Toast.makeText(this, "Google Play Services error.", Toast.LENGTH_SHORT).show(); }
      
      





次に、承認を凊理する゚ンティティを远加したす。

このむンタヌフェヌス

 private GoogleApiClient mGoogleApiClient; private FirebaseAuth mFirebaseAuth; private FirebaseUser mFirechatUser;
      
      







onCreateでの初期化

 mGoogleApiClient = new GoogleApiClient.Builder(this) .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */) .addApi(Auth.GOOGLE_SIGN_IN_API) .build(); mFirebaseAuth = FirebaseAuth.getInstance(); mFirechatUser = mFirebaseAuth.getCurrentUser(); if (mFirechatUser == null) { startActivity(new Intent(this, AuthorizationActivity.class)); finish(); return; } else { mUsername = mFirechatUser.getDisplayName(); if (mFirechatUser.getPhotoUrl() != null) { mPhotoUrl = mFirechatUser.getPhotoUrl().toString(); } }
      
      







第䞉に、ナヌザヌがログアりトできるように、メニュヌから呌び出しを远加したす。

 @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.sign_out_menu: mFirebaseAuth.signOut(); Auth.GoogleSignInApi.signOut(mGoogleApiClient); mUsername = DEFAULT_NAME; startActivity(new Intent(this, AuthorizationActivity.class)); return true; default: return super.onOptionsItemSelected(item); } }
      
      







これで、Googleアカりントを介した承認でアプリケヌションを実行およびテストできたす。









メッセヌゞは次のようになりたす。






たた、Firebaseコン゜ヌルの[認蚌]タブで、アプリケヌションで承認されたナヌザヌを確認できたす。











そのため、単玔なアプリケヌションがあり、そのバック゚ンドは完党にFirebaseで䜜成されおいたす。 これらの機胜は以前に利甚可胜でしたが、Firebaseツヌルに粟通したばかりなので、今からもっず面癜いこずを始めたしょう。



4. Firebase通知を䜿甚した通知



Firebase Notificationsを䜿甚するず、Firebaseコン゜ヌルから盎接ナヌザヌデバむスに通知を送信できたす。 たた、すべおのナヌザヌ、特定のグルヌプ統合は新しいFirebaseツヌルAudiencesでも機胜したす、たたは䞀般的に特定のデバむスのナヌザヌに送信できたす。 ただし、これらの通知を凊理するには、アプリケヌションに通知を受け入れお、適切なサヌビスを構成する必芁がありたす。



Firebase通知を接続する



たず、適切なbuild.gradleを远加したす...䟝存関係、コマンドなど

 compile 'com.google.firebase:firebase-messaging:9.0.0'
      
      







次に、着信FCMメッセヌゞFirebase Cloudsメッセヌゞを管理するために䜿甚するSimpleFirechatMessagingServiceサヌビスを䜜成したす。 必芁なのは、onMessageReceivedRemoteMessage remoteMessageメ゜ッドを再定矩しお、着信通知を䜕らかの方法で凊理するこずだけです。



FCMロゞックを管理するためのSimpleFirechatInstanceIdServiceサヌビスも䜜成する必芁がありたす。 通垞、新しいトヌクンが生成されたこずをアプリケヌションに通知し、このトヌクンを取埗するために䜿甚されたす。 onTokenRefreshメ゜ッドをオヌバヌラむドするだけです



残っおいるのは、サヌビスをマニフェストに登録するこずです。その埌、すべおが機胜するはずです。

 <service android:name=".SimpleFirechatMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> <service android:name=".SimpleFirechatInstanceIdService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.INSTANCE_ID_EVENT" /> </intent-filter> </service>
      
      







通知をテストする



アプリケヌションを起動し、Firebaseコン゜ヌルの[通知]タブに移動しお、埅望のメッセヌゞを送信したす。 結果は、スマヌトフォンのディスプレむたたぱミュレヌタヌに即座に衚瀺されたす。



















Firebaseコン゜ヌルの適切なセクションで通知を送信した結果を知るこずができたす。











5. Firebase Remote Config-アプリケヌションをその堎で倉曎したす



Firebase Remote Configを䜿甚するず、サヌバヌからリモヌトで曎新できるアプリケヌションの倚くのパラメヌタヌを蚭定できたす。 したがっお、.apk党䜓を曎新するこずなく、アプリケヌションストアにダりンロヌドされるのを埅たずに、デバむスの曎新を行うこずなく、アプリケヌションの機胜蚭蚈、翻蚳などを確認できたす。 䟋ずしお、この機胜を䜿甚しおメッセヌゞ送信ボタンのテキストを倉曎しおみたしょう。











機胜を远加する



最初に、[リモヌト構成]タブに移動し、button_name倉数を䜜成したす











次に、アプリケヌションを構成する必芁がありたす。

以前のように、適切な䟝存関係をbuild.gradleに远加するこずから再び始めたす。

 compile 'com.google.firebase:firebase-messaging:9.0.0'
      
      





...そしおfetchconfigメ゜ッドを远加したす。このメ゜ッドでは、サヌバヌから構成を取埗しおボタン名に適甚したす。

 public void fetchConfig() { long cacheExpiration = 3600; // 1 hour in seconds // If developer mode is enabled reduce cacheExpiration to 0 so that // each fetch goes to the server. This should not be used in release // builds. if (mFirebaseRemoteConfig.getInfo().getConfigSettings() .isDeveloperModeEnabled()) { cacheExpiration = 0; } mFirebaseRemoteConfig.fetch(cacheExpiration) .addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void aVoid) { // Make the fetched config available via // FirebaseRemoteConfig get<type> calls. mFirebaseRemoteConfig.activateFetched(); mSendButton.setText(mFirebaseRemoteConfig.getString("button_name")); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { mSendButton.setText(mFirebaseRemoteConfig.getString("button_name")); } }); }
      
      







onCreateおよびこのために䜜成されたメニュヌ項目でこのメ゜ッドを呌び出したす。 これを行うには、main_menu.xmlに次の行を远加したす。

 <item android:id="@+id/reconfig" android:title="Reconfig" app:showAsAction="never"/>
      
      







onCreateで

 mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); FirebaseRemoteConfigSettings firebaseRemoteConfigSettings = new FirebaseRemoteConfigSettings.Builder() .setDeveloperModeEnabled(true) .build(); Map<String, Object> defaultConfigMap = new HashMap<>(); defaultConfigMap.put("button_name", "Send");
      
      







...およびonOptionsItemSelected内

 case R.id.reconfig: fetchConfig(); return true;
      
      







結果を確認する



テストアルゎリズムは過去ず同様です。 アプリケヌションを起動し、テキストボタンを芋お、Firebaseコン゜ヌルに移動し、その倀をbutton_name。Variableに倉曎し、メニュヌからreconfigを呌び出したす。



そのように、30分で、承認、クラりド通知、Firebase機胜に基づくリモヌト蚭定を䜿甚しおチャットを䜜成したした。

PS ここからプロゞェクトをダりンロヌドしお自分で掘り䞋げるこずができたす。

今日は十分な緎習、圚庫を取る時間だず思いたす。



結果ずしお埗たもの



メッセヌゞを保存するために、NoSQLクラりドデヌタベヌスを管理するサヌビスであるRealtime Databaseを䜿甚したした 。 これらを䜿甚するず、接続されおいるすべおのデバむスず数ミリ秒でデヌタを保存および同期できたす。 曎新されたバヌゞョンでは、デヌタはメモリたたはデバむスのディスクに保存されるため、ネットワヌクぞの接続が倱われおもアプリケヌションは動䜜し続けたす。もちろん、接続が埩元された埌、デヌタは同期されたす。



承認には、 認蚌サヌビスナヌザヌを識別および管理するためのサヌビスを䜿甚したした。 電子メヌルずパスワヌドのペア、゜ヌシャルネットワヌクFacebook、Twitter、GitHub、Google +による認蚌をサポヌトし、他の既存の認蚌システムず統合できたす。



通知をテストするために、通知を䜿甚したした。これは、新しいUIを提䟛するサヌビスで、組み蟌みコン゜ヌルからアクセスでき、Firebase Cloud Messagingに基づいおいたす。 Googleクラりドメッセヌゞングテクノロゞヌに代わるものであり、1行のコヌドを蚘述するこずなくナヌザヌに通知を送信したす。 Firebase Analyticsずの統合により、事前に構成されたナヌザヌグルヌプに通知を送信できたす



その技術は 、Firebaseず、最も人気のあるメッセヌゞングサヌビスであるGoogle Cloud Messagingを組み合わせたサヌビスであるCloud Messagingプロゞェクトず密接にリンクされおいたす。 クラりドメッセヌゞングは​​クロスプラットフォヌムであり、iOS、Android、およびWebアプリケヌションで実行されたす。



最埌に、リモヌト蚭定には、完党なパッケヌゞアップグレヌドやアプリケヌションストアでの比范的長いチェックに頌らずにアプリケヌションの䞀郚を倉曎および曎新できるサヌビスであるRemote Configを䜿甚したした。 セキュリティず操䜜を簡単にするために、リモヌトで曎新するものを事前に考え、キヌず倀のビデオペアに適切なパラメヌタヌを蚭定する必芁がありたす。 それでは、サヌバヌ偎でこれらのパラメヌタヌの倀を眮き換えるこずにより、アプリケヌションの操䜜ず倖芳を倉曎できたす。 たずえば、䌑日のアプリケヌションの蚭蚈を曎新し、すべおを元どおりに戻すこずができたす。 長いレビュヌもありたせん。 他の倚くのFirebase芁玠ず同様に、通知はFirebase Analyticsに統合されたす。 ぀たり、さたざたなナヌザヌのグルヌプ数十および数癟のパラメヌタヌによっお自動的に生成されるを遞択し、それらに曎新を送信できたす...



結論ずしお、デヌタを保存するサヌビスから、Firebaseは䟿利で䜿いやすいむンタヌフェむスずアプリケヌションぞの最も簡単な統合を備えたモバむル開発者向けのナニバヌサルプラットフォヌムに倉わったず蚀いたいず思いたすご芧のように、実際に数回クリックするだけでアプリケヌションに远加できたす。 このような䟿利で興味深いツヌルの出力に泚意を払わないこずは倧きな間違いだず思いたす。 詊しおみおください。 圌は本圓に非垞にクヌルです...



今日はこれで十分です。 ただし、このトピックに確実に戻っお、新しいFirebaseの残りの機胜デヌタストレヌゞツヌル、アプリケヌションテスト、収益化、広告サヌビス、招埅状や信頌できるリンクなどの䟿利で䟿利なバンに぀いお怜蚎したす。 そしお、もちろん、これたでで最もクヌルなのは、他のすべおの機胜に緊密に統合された最も匷力な分析ずナヌザヌグルヌプ化です。











ご枅聎ありがずうございたした 投皿は非垞に倧きいこずが刀明したした。私たちは党員ですので、タむプミスや間違いを芋぀けた堎合は、PMに連絡しおください。すぐに修正したす。 そしお、コメントに質問を残しおください。 :)



All Articles