diff --git a/android-start/app/build.gradle b/android-start/app/build.gradle
index 3074195db..83a98c9ef 100644
--- a/android-start/app/build.gradle
+++ b/android-start/app/build.gradle
@@ -42,17 +42,17 @@ dependencies {
compile 'com.android.support:appcompat-v7:25.0.0'
// Google
- compile 'com.google.android.gms:play-services-auth:10.0.0'
+ compile 'com.google.android.gms:play-services-auth:10.0.1'
// Firebase
- compile 'com.google.firebase:firebase-database:10.0.0'
- compile 'com.google.firebase:firebase-auth:10.0.0'
- compile 'com.google.firebase:firebase-config:10.0.0'
- compile 'com.google.android.gms:play-services-appinvite:10.0.0'
- compile 'com.google.firebase:firebase-messaging:10.0.0'
- compile 'com.google.android.gms:play-services-ads:10.0.0'
- compile 'com.google.firebase:firebase-crash:10.0.0'
- compile 'com.google.firebase:firebase-appindexing:10.0.0'
+ compile 'com.google.firebase:firebase-database:10.0.1'
+ compile 'com.google.firebase:firebase-auth:10.0.1'
+ compile 'com.google.firebase:firebase-config:10.0.1'
+ compile 'com.google.android.gms:play-services-appinvite:10.0.1'
+ compile 'com.google.firebase:firebase-messaging:10.0.1'
+ compile 'com.google.android.gms:play-services-ads:10.0.1'
+ compile 'com.google.firebase:firebase-crash:10.0.1'
+ compile 'com.google.firebase:firebase-appindexing:10.0.1'
// Firebase UI
compile 'com.firebaseui:firebase-ui-database:0.4.0'
diff --git a/android-start/app/src/main/AndroidManifest.xml b/android-start/app/src/main/AndroidManifest.xml
index e0833dfa9..0d931d19a 100644
--- a/android-start/app/src/main/AndroidManifest.xml
+++ b/android-start/app/src/main/AndroidManifest.xml
@@ -8,16 +8,28 @@
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
+
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/android-start/app/src/main/java/com/google/firebase/codelab/friendlychat/MainActivity.java b/android-start/app/src/main/java/com/google/firebase/codelab/friendlychat/MainActivity.java
index e887e1473..19b4aed1b 100644
--- a/android-start/app/src/main/java/com/google/firebase/codelab/friendlychat/MainActivity.java
+++ b/android-start/app/src/main/java/com/google/firebase/codelab/friendlychat/MainActivity.java
@@ -104,6 +104,11 @@ public MessageViewHolder(View v) {
private EditText mMessageEditText;
// Firebase instance variables
+ private FirebaseAuth mFirebaseAuth;
+ private FirebaseUser mFirebaseUser;
+ private DatabaseReference mFirebaseDatabaseReference;
+ private FirebaseRecyclerAdapter
+ mFirebaseAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -113,6 +118,21 @@ protected void onCreate(Bundle savedInstanceState) {
// Set default username is anonymous.
mUsername = ANONYMOUS;
+ // Initialize Firebase Auth
+ mFirebaseAuth = FirebaseAuth.getInstance();
+ mFirebaseUser = mFirebaseAuth.getCurrentUser();
+ if (mFirebaseUser == null) {
+ // Not signed in, launch the Sign In activity
+ startActivity(new Intent(this, SignInActivity.class));
+ finish();
+ return;
+ } else {
+ mUsername = mFirebaseUser.getDisplayName();
+ if (mFirebaseUser.getPhotoUrl() != null) {
+ mPhotoUrl = mFirebaseUser.getPhotoUrl().toString();
+ }
+ }
+
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API)
@@ -125,7 +145,54 @@ protected void onCreate(Bundle savedInstanceState) {
mLinearLayoutManager.setStackFromEnd(true);
mMessageRecyclerView.setLayoutManager(mLinearLayoutManager);
- mProgressBar.setVisibility(ProgressBar.INVISIBLE);
+ // New child entries
+ mFirebaseDatabaseReference = FirebaseDatabase.getInstance().getReference();
+ mFirebaseAdapter = new FirebaseRecyclerAdapter(
+ FriendlyMessage.class,
+ R.layout.item_message,
+ MessageViewHolder.class,
+ mFirebaseDatabaseReference.child(MESSAGES_CHILD)) {
+
+ @Override
+ protected void populateViewHolder(MessageViewHolder viewHolder,
+ FriendlyMessage friendlyMessage, int position) {
+ mProgressBar.setVisibility(ProgressBar.INVISIBLE);
+ viewHolder.messageTextView.setText(friendlyMessage.getText());
+ viewHolder.messengerTextView.setText(friendlyMessage.getName());
+ if (friendlyMessage.getPhotoUrl() == null) {
+ viewHolder.messengerImageView
+ .setImageDrawable(ContextCompat
+ .getDrawable(MainActivity.this,
+ R.drawable.ic_account_circle_black_36dp));
+ } else {
+ Glide.with(MainActivity.this)
+ .load(friendlyMessage.getPhotoUrl())
+ .into(viewHolder.messengerImageView);
+ }
+ }
+ };
+
+ mFirebaseAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
+ @Override
+ public void onItemRangeInserted(int positionStart, int itemCount) {
+ super.onItemRangeInserted(positionStart, itemCount);
+ int friendlyMessageCount = mFirebaseAdapter.getItemCount();
+ int lastVisiblePosition =
+ mLinearLayoutManager.findLastCompletelyVisibleItemPosition();
+ // If the recycler view is initially being loaded or the
+ // user is at the bottom of the list, scroll to the bottom
+ // of the list to show the newly added message.
+ if (lastVisiblePosition == -1 ||
+ (positionStart >= (friendlyMessageCount - 1) &&
+ lastVisiblePosition == (positionStart - 1))) {
+ mMessageRecyclerView.scrollToPosition(positionStart);
+ }
+ }
+ });
+
+ mMessageRecyclerView.setLayoutManager(mLinearLayoutManager);
+ mMessageRecyclerView.setAdapter(mFirebaseAdapter);
mMessageEditText = (EditText) findViewById(R.id.messageEditText);
mMessageEditText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(mSharedPreferences
@@ -153,7 +220,13 @@ public void afterTextChanged(Editable editable) {
mSendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- // Send messages on click.
+ FriendlyMessage friendlyMessage = new
+ FriendlyMessage(mMessageEditText.getText().toString(),
+ mUsername,
+ mPhotoUrl);
+ mFirebaseDatabaseReference.child(MESSAGES_CHILD)
+ .push().setValue(friendlyMessage);
+ mMessageEditText.setText("");
}
});
}
@@ -189,7 +262,38 @@ public boolean onCreateOptionsMenu(Menu menu) {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
- return super.onOptionsItemSelected(item);
+ switch (item.getItemId()) {
+
+ case R.id.sign_out_menu:
+ mFirebaseAuth.signOut();
+ Auth.GoogleSignInApi.signOut(mGoogleApiClient);
+ mUsername = ANONYMOUS;
+ startActivity(new Intent(this, SignInActivity.class));
+ return true;
+
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+ private Indexable getMessageIndexable(FriendlyMessage friendlyMessage) {
+ PersonBuilder sender = Indexables.personBuilder()
+ .setIsSelf(mUsername == friendlyMessage.getName())
+ .setName(friendlyMessage.getName())
+ .setUrl(MESSAGE_URL.concat(friendlyMessage.getId() + "/sender"));
+
+ PersonBuilder recipient = Indexables.personBuilder()
+ .setName(mUsername)
+ .setUrl(MESSAGE_URL.concat(friendlyMessage.getId() + "/recipient"));
+
+ Indexable messageToIndex = Indexables.messageBuilder()
+ .setName(friendlyMessage.getText())
+ .setUrl(MESSAGE_URL.concat(friendlyMessage.getId()))
+ .setSender(sender)
+ .setRecipient(recipient)
+ .build();
+
+ return messageToIndex;
}
@Override
diff --git a/android-start/app/src/main/java/com/google/firebase/codelab/friendlychat/SignInActivity.java b/android-start/app/src/main/java/com/google/firebase/codelab/friendlychat/SignInActivity.java
index 0a158b816..464b023bc 100644
--- a/android-start/app/src/main/java/com/google/firebase/codelab/friendlychat/SignInActivity.java
+++ b/android-start/app/src/main/java/com/google/firebase/codelab/friendlychat/SignInActivity.java
@@ -48,6 +48,7 @@ public class SignInActivity extends AppCompatActivity implements
private GoogleApiClient mGoogleApiClient;
// Firebase instance variables
+ private FirebaseAuth mFirebaseAuth;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -71,16 +72,65 @@ protected void onCreate(Bundle savedInstanceState) {
.build();
// Initialize FirebaseAuth
+ mFirebaseAuth = FirebaseAuth.getInstance();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.sign_in_button:
+ signIn();
break;
}
}
+ private void signIn() {
+ Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
+ startActivityForResult(signInIntent, RC_SIGN_IN);
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+
+ // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
+ if (requestCode == RC_SIGN_IN) {
+ GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
+ if (result.isSuccess()) {
+ // Google Sign In was successful, authenticate with Firebase
+ GoogleSignInAccount account = result.getSignInAccount();
+ firebaseAuthWithGoogle(account);
+ } else {
+ // Google Sign In failed
+ Log.e(TAG, "Google Sign In failed.");
+ }
+ }
+ }
+
+ private void firebaseAuthWithGoogle(GoogleSignInAccount acct) {
+ Log.d(TAG, "firebaseAuthWithGooogle:" + acct.getId());
+ AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
+ mFirebaseAuth.signInWithCredential(credential)
+ .addOnCompleteListener(this, new OnCompleteListener() {
+ @Override
+ public void onComplete(@NonNull Task task) {
+ Log.d(TAG, "signInWithCredential:onComplete:" + task.isSuccessful());
+
+ // If sign in fails, display a message to the user. If sign in succeeds
+ // the auth state listener will be notified and logic to handle the
+ // signed in user can be handled in the listener.
+ if (!task.isSuccessful()) {
+ Log.w(TAG, "signInWithCredential", task.getException());
+ Toast.makeText(SignInActivity.this, "Authentication failed.",
+ Toast.LENGTH_SHORT).show();
+ } else {
+ startActivity(new Intent(SignInActivity.this, MainActivity.class));
+ finish();
+ }
+ }
+ });
+ }
+
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
// An unresolvable error has occurred and Google APIs (including Sign-In) will not
diff --git a/android-start/build.gradle b/android-start/build.gradle
index f5a38fc74..7fb4bbf1a 100644
--- a/android-start/build.gradle
+++ b/android-start/build.gradle
@@ -6,7 +6,7 @@ buildscript {
mavenLocal()
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.2.2'
+ classpath 'com.android.tools.build:gradle:2.2.3'
classpath 'com.google.gms:google-services:3.0.0'
// NOTE: Do not place your application dependencies here; they belong
diff --git a/android/build.gradle b/android/build.gradle
index 402c017f8..ffaa9e304 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -5,7 +5,7 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.2.2'
+ classpath 'com.android.tools.build:gradle:2.2.3'
classpath 'com.google.gms:google-services:3.0.0'
// NOTE: Do not place your application dependencies here; they belong