Created
February 16, 2018 13:19
-
-
Save nuhkoca/243743134657c327835f48d50d0ea76b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Copyright Google Inc. All Rights Reserved. | |
* <p/> | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* <p/> | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* <p/> | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
package com.google.firebase.udacity.friendlychat; | |
import android.content.Intent; | |
import android.net.Uri; | |
import android.os.Bundle; | |
import android.support.annotation.NonNull; | |
import android.support.v7.app.AppCompatActivity; | |
import android.text.Editable; | |
import android.text.InputFilter; | |
import android.text.TextWatcher; | |
import android.util.Log; | |
import android.view.Menu; | |
import android.view.MenuInflater; | |
import android.view.MenuItem; | |
import android.view.View; | |
import android.widget.Button; | |
import android.widget.EditText; | |
import android.widget.ImageButton; | |
import android.widget.ListView; | |
import android.widget.ProgressBar; | |
import android.widget.Toast; | |
import com.firebase.ui.auth.AuthUI; | |
import com.google.android.gms.tasks.OnFailureListener; | |
import com.google.android.gms.tasks.OnSuccessListener; | |
import com.google.firebase.auth.FirebaseAuth; | |
import com.google.firebase.auth.FirebaseUser; | |
import com.google.firebase.database.ChildEventListener; | |
import com.google.firebase.database.DataSnapshot; | |
import com.google.firebase.database.DatabaseError; | |
import com.google.firebase.database.DatabaseReference; | |
import com.google.firebase.database.FirebaseDatabase; | |
import com.google.firebase.remoteconfig.FirebaseRemoteConfig; | |
import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; | |
import com.google.firebase.storage.FirebaseStorage; | |
import com.google.firebase.storage.StorageReference; | |
import com.google.firebase.storage.UploadTask; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
public class MainActivity extends AppCompatActivity { | |
private static final String TAG = "MainActivity"; | |
private static final int RC_SIGN_IN = 123; | |
private static final int RC_PHOTO_PICKER = 124; | |
public static final String ANONYMOUS = "anonymous"; | |
public static final int DEFAULT_MSG_LENGTH_LIMIT = 1000; | |
public static final String FRIENDLY_MSG_LENGTH_KEY = "friendly_msg_length"; | |
private EditText mMessageEditText; | |
private Button mSendButton; | |
private MessageAdapter mMessageAdapter; | |
private ChildEventListener mChildEventListener; | |
private String mUsername; | |
private DatabaseReference mDatabaseReference; | |
private FirebaseAuth mFirebaseAuth; | |
private FirebaseAuth.AuthStateListener mAuthStateListener; | |
private FirebaseStorage mFirebaseStorage; | |
private FirebaseDatabase mFirebaseDatabase; | |
private StorageReference mStorageReference; | |
private FirebaseRemoteConfig mFirebaseRemoteConfig; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
mSendButton = findViewById(R.id.sendButton); | |
mUsername = ANONYMOUS; | |
mFirebaseDatabase = FirebaseDatabase.getInstance(); | |
mFirebaseAuth = FirebaseAuth.getInstance(); | |
mFirebaseStorage = FirebaseStorage.getInstance(); | |
mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance(); | |
mDatabaseReference = mFirebaseDatabase.getReference().child("messages"); | |
mStorageReference = mFirebaseStorage.getReference().child("chat_photos"); | |
// Initialize references to views | |
ProgressBar mProgressBar = findViewById(R.id.progressBar); | |
ListView mMessageListView = findViewById(R.id.messageListView); | |
ImageButton mPhotoPickerButton = findViewById(R.id.photoPickerButton); | |
mMessageEditText = findViewById(R.id.messageEditText); | |
// Initialize message ListView and its adapter | |
List<FriendlyMessage> friendlyMessages = new ArrayList<>(); | |
mMessageAdapter = new MessageAdapter(this, R.layout.item_message, friendlyMessages); | |
mMessageListView.setAdapter(mMessageAdapter); | |
// Initialize progress bar | |
mProgressBar.setVisibility(ProgressBar.INVISIBLE); | |
// ImagePickerButton shows an image picker to upload a image for a message | |
mPhotoPickerButton.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View view) { | |
Intent intent = new Intent(Intent.ACTION_GET_CONTENT); | |
intent.setType("image/jpeg"); | |
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true); | |
startActivityForResult(Intent.createChooser(intent, "Complete action using"), RC_PHOTO_PICKER); | |
} | |
}); | |
// Enable Send button when there's text to send | |
mMessageEditText.addTextChangedListener(new TextWatcher() { | |
@Override | |
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { | |
} | |
@Override | |
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { | |
if (charSequence.toString().trim().length() > 0) { | |
mSendButton.setEnabled(true); | |
} else { | |
mSendButton.setEnabled(false); | |
} | |
} | |
@Override | |
public void afterTextChanged(Editable editable) { | |
} | |
}); | |
mMessageEditText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(DEFAULT_MSG_LENGTH_LIMIT)}); | |
// Send button sends a message and clears the EditText | |
mSendButton.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View view) { | |
// TODO: Send messages on click | |
FriendlyMessage friendlyMessage = new FriendlyMessage(mMessageEditText.getText().toString(), mUsername, null); | |
mDatabaseReference.push().setValue(friendlyMessage); | |
// Clear input box | |
mMessageEditText.setText(""); | |
} | |
}); | |
mAuthStateListener = new FirebaseAuth.AuthStateListener() { | |
@Override | |
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { | |
FirebaseUser user = firebaseAuth.getCurrentUser(); | |
if (user != null) { | |
onSignedInInitialize(user.getDisplayName()); | |
Toast.makeText(MainActivity.this, "You are now signed in. Welcome to FriendlyChat!", Toast.LENGTH_SHORT).show(); | |
} else { | |
onSignedOutCleanUp(); | |
startActivityForResult( | |
AuthUI.getInstance() | |
.createSignInIntentBuilder() | |
.setIsSmartLockEnabled(false) | |
.setAvailableProviders(Arrays.asList( | |
new AuthUI.IdpConfig.EmailBuilder().build(), | |
new AuthUI.IdpConfig.GoogleBuilder().build())) | |
.build(), | |
RC_SIGN_IN); | |
} | |
} | |
}; | |
FirebaseRemoteConfigSettings configSettings = new FirebaseRemoteConfigSettings.Builder() | |
.setDeveloperModeEnabled(true) | |
.build(); | |
mFirebaseRemoteConfig.setConfigSettings(configSettings); | |
Map<String , Object> defaultConfig = new HashMap<>(); | |
defaultConfig.put(FRIENDLY_MSG_LENGTH_KEY, DEFAULT_MSG_LENGTH_LIMIT); | |
mFirebaseRemoteConfig.setDefaults(defaultConfig); | |
fetchConfig(); | |
} | |
private void fetchConfig() { | |
long cacheExpiration = 3600; | |
if (mFirebaseRemoteConfig.getInfo().getConfigSettings().isDeveloperModeEnabled()) { | |
cacheExpiration = 0; | |
} | |
mFirebaseRemoteConfig.fetch(cacheExpiration) | |
.addOnSuccessListener(new OnSuccessListener<Void>() { | |
@Override | |
public void onSuccess(Void aVoid) { | |
mFirebaseRemoteConfig.activateFetched(); | |
applyRetrievedLengthLimit(); | |
} | |
}) | |
.addOnFailureListener(new OnFailureListener() { | |
@Override | |
public void onFailure(@NonNull Exception e) { | |
Log.w(TAG, "Error while fetching!", e); | |
applyRetrievedLengthLimit(); | |
} | |
}); | |
} | |
private void applyRetrievedLengthLimit() { | |
Long friendly_msg_length = mFirebaseRemoteConfig.getLong(FRIENDLY_MSG_LENGTH_KEY); | |
mMessageEditText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(friendly_msg_length.intValue())}); | |
Log.d(TAG, FRIENDLY_MSG_LENGTH_KEY + " = " + friendly_msg_length); | |
} | |
@Override | |
protected void onActivityResult(int requestCode, int resultCode, Intent data) { | |
super.onActivityResult(requestCode, resultCode, data); | |
if (requestCode == RC_SIGN_IN) { | |
if (resultCode == RESULT_OK) { | |
Toast.makeText(MainActivity.this, "Signed in!", Toast.LENGTH_SHORT).show(); | |
} else if (resultCode == RESULT_CANCELED) { | |
Toast.makeText(MainActivity.this, "Signed out!", Toast.LENGTH_SHORT).show(); | |
finish(); | |
} | |
} | |
else if (requestCode == RC_PHOTO_PICKER && resultCode == RESULT_OK){ | |
Uri selectedImage = data.getData(); | |
StorageReference ref = null; | |
if (selectedImage != null) { | |
ref = mStorageReference.child(selectedImage.getLastPathSegment()); | |
} | |
if (ref != null) { | |
ref.putFile(selectedImage).addOnSuccessListener(this, new OnSuccessListener<UploadTask.TaskSnapshot>() { | |
@Override | |
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { | |
Uri downloadURL = taskSnapshot.getDownloadUrl(); | |
FriendlyMessage message = null; | |
if (downloadURL != null) { | |
message = new FriendlyMessage(null, mUsername, downloadURL.toString()); | |
} | |
mDatabaseReference.push().setValue(message); | |
} | |
}); | |
} | |
} | |
} | |
private void attachDatabaseReadListener() { | |
if (mChildEventListener == null) { | |
mChildEventListener = new ChildEventListener() { | |
@Override | |
public void onChildAdded(DataSnapshot dataSnapshot, String s) { | |
FriendlyMessage friendlyMessage = dataSnapshot.getValue(FriendlyMessage.class); | |
mMessageAdapter.add(friendlyMessage); | |
} | |
@Override | |
public void onChildChanged(DataSnapshot dataSnapshot, String s) { | |
} | |
@Override | |
public void onChildRemoved(DataSnapshot dataSnapshot) { | |
} | |
@Override | |
public void onChildMoved(DataSnapshot dataSnapshot, String s) { | |
} | |
@Override | |
public void onCancelled(DatabaseError databaseError) { | |
} | |
}; | |
mDatabaseReference.addChildEventListener(mChildEventListener); | |
} | |
} | |
private void detachDatabaseReadListener() { | |
if (mChildEventListener != null) { | |
mDatabaseReference.removeEventListener(mChildEventListener); | |
mChildEventListener = null; | |
} | |
} | |
private void onSignedOutCleanUp() { | |
mUsername = ANONYMOUS; | |
mMessageAdapter.clear(); | |
detachDatabaseReadListener(); | |
} | |
private void onSignedInInitialize(String displayName) { | |
mUsername = displayName; | |
attachDatabaseReadListener(); | |
} | |
@Override | |
public boolean onCreateOptionsMenu(Menu menu) { | |
MenuInflater inflater = getMenuInflater(); | |
inflater.inflate(R.menu.main_menu, menu); | |
return true; | |
} | |
@Override | |
public boolean onOptionsItemSelected(MenuItem item) { | |
int id = item.getItemId(); | |
if (id==R.id.sign_out_menu){ | |
AuthUI.getInstance().signOut(this); | |
return true; | |
}else { | |
return super.onOptionsItemSelected(item); | |
} | |
} | |
@Override | |
protected void onPause() { | |
super.onPause(); | |
if (mFirebaseAuth != null) { | |
mFirebaseAuth.removeAuthStateListener(mAuthStateListener); | |
} | |
detachDatabaseReadListener(); | |
mMessageAdapter.clear(); | |
} | |
@Override | |
protected void onResume() { | |
super.onResume(); | |
mFirebaseAuth.addAuthStateListener(mAuthStateListener); | |
} | |
} | |
© 2018 GitHub, Inc. | |
Terms | |
Privacy | |
Security | |
Status | |
Help | |
Contact GitHub | |
API | |
Training | |
Shop | |
Blog | |
About |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment