└── FirebaseDirectMessage ├── .firebaserc ├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── gradle.xml ├── misc.xml ├── modules.xml └── runConfigurations.xml ├── app ├── .gitignore ├── build.gradle ├── google-services.json ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── codingwithmitch │ │ └── com │ │ └── firebasedirectmessage │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── codingwithmitch │ │ │ └── com │ │ │ └── firebasedirectmessage │ │ │ ├── LoginActivity.java │ │ │ ├── RegisterActivity.java │ │ │ ├── UserListActivity.java │ │ │ ├── models │ │ │ ├── Message.java │ │ │ └── User.java │ │ │ └── utility │ │ │ ├── MessageDialog.java │ │ │ ├── MyFirebaseInstanceIDService.java │ │ │ ├── MyFirebaseMessagingService.java │ │ │ └── UserAdapter.java │ └── res │ │ ├── drawable-hdpi │ │ ├── ic_android.png │ │ └── ic_android_blue.png │ │ ├── drawable-mdpi │ │ ├── ic_android.png │ │ └── ic_android_blue.png │ │ ├── drawable-xhdpi │ │ ├── ic_android.png │ │ └── ic_android_blue.png │ │ ├── drawable-xxhdpi │ │ ├── ic_android.png │ │ └── ic_android_blue.png │ │ ├── layout │ │ ├── activity_login.xml │ │ ├── activity_register.xml │ │ ├── activity_userlist.xml │ │ ├── dialog_message.xml │ │ └── layout_user_listitem.xml │ │ ├── menu │ │ └── menu.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── codingwithmitch │ └── com │ └── firebasedirectmessage │ └── ExampleUnitTest.java ├── build.gradle ├── firebase.json ├── gradle.properties ├── gradlew ├── gradlew.bat └── settings.gradle /FirebaseDirectMessage/.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "fir-directmessage" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /FirebaseDirectMessage/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /FirebaseDirectMessage/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /FirebaseDirectMessage/.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /FirebaseDirectMessage/.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /FirebaseDirectMessage/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | -------------------------------------------------------------------------------- /FirebaseDirectMessage/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /FirebaseDirectMessage/.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /FirebaseDirectMessage/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /FirebaseDirectMessage/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 26 5 | buildToolsVersion "27.0.1" 6 | defaultConfig { 7 | applicationId "codingwithmitch.com.firebasedirectmessage" 8 | minSdkVersion 16 9 | targetSdkVersion 26 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 25 | exclude group: 'com.android.support', module: 'support-annotations' 26 | }) 27 | compile 'com.android.support:appcompat-v7:26.+' 28 | compile 'com.android.support.constraint:constraint-layout:1.0.2' 29 | testCompile 'junit:junit:4.12' 30 | 31 | //RecyclerView 32 | compile 'com.android.support:recyclerview-v7:26.+' 33 | 34 | //Firebase Authentication 35 | compile 'com.google.firebase:firebase-auth:11.4.0' 36 | 37 | //Firebase Realtime Database 38 | compile 'com.google.firebase:firebase-database:11.4.0' 39 | 40 | //Firebase Cloud Messaging 41 | compile 'com.google.firebase:firebase-messaging:11.4.0' 42 | 43 | } 44 | apply plugin: 'com.google.gms.google-services' -------------------------------------------------------------------------------- /FirebaseDirectMessage/app/google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "370887741467", 4 | "firebase_url": "https://fir-directmessage.firebaseio.com", 5 | "project_id": "fir-directmessage", 6 | "storage_bucket": "fir-directmessage.appspot.com" 7 | }, 8 | "client": [ 9 | { 10 | "client_info": { 11 | "mobilesdk_app_id": "1:370887741467:android:d39be30ed3a0c82b", 12 | "android_client_info": { 13 | "package_name": "codingwithmitch.com.firebasedirectmessage" 14 | } 15 | }, 16 | "oauth_client": [ 17 | { 18 | "client_id": "370887741467-ov8m6g35t0v90v46kusg69fmpqaruemv.apps.googleusercontent.com", 19 | "client_type": 3 20 | } 21 | ], 22 | "api_key": [ 23 | { 24 | "current_key": "AIzaSyAGXeB03YKB-qSGvOqou-QT5jO9WmY5ZPc" 25 | } 26 | ], 27 | "services": { 28 | "analytics_service": { 29 | "status": 1 30 | }, 31 | "appinvite_service": { 32 | "status": 1, 33 | "other_platform_oauth_client": [] 34 | }, 35 | "ads_service": { 36 | "status": 2 37 | } 38 | } 39 | } 40 | ], 41 | "configuration_version": "1" 42 | } -------------------------------------------------------------------------------- /FirebaseDirectMessage/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Users\User\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /FirebaseDirectMessage/app/src/androidTest/java/codingwithmitch/com/firebasedirectmessage/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package codingwithmitch.com.firebasedirectmessage; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("codingwithmitch.com.firebasedirectmessage", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /FirebaseDirectMessage/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 14 | 15 | 17 | 18 | 19 | 20 | 21 | 22 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /FirebaseDirectMessage/app/src/main/java/codingwithmitch/com/firebasedirectmessage/LoginActivity.java: -------------------------------------------------------------------------------- 1 | package codingwithmitch.com.firebasedirectmessage; 2 | 3 | 4 | import android.app.Dialog; 5 | import android.content.Intent; 6 | import android.os.Bundle; 7 | import android.support.annotation.NonNull; 8 | import android.support.v7.app.AppCompatActivity; 9 | import android.util.Log; 10 | import android.view.View; 11 | import android.view.WindowManager; 12 | import android.widget.Button; 13 | import android.widget.EditText; 14 | import android.widget.ProgressBar; 15 | import android.widget.TextView; 16 | import android.widget.Toast; 17 | 18 | import com.google.android.gms.common.ConnectionResult; 19 | import com.google.android.gms.common.GoogleApiAvailability; 20 | import com.google.android.gms.tasks.OnCompleteListener; 21 | import com.google.android.gms.tasks.OnFailureListener; 22 | import com.google.android.gms.tasks.Task; 23 | import com.google.firebase.auth.AuthResult; 24 | import com.google.firebase.auth.FirebaseAuth; 25 | import com.google.firebase.auth.FirebaseUser; 26 | 27 | 28 | 29 | public class LoginActivity extends AppCompatActivity { 30 | 31 | private static final String TAG = "LoginActivity"; 32 | //constants 33 | private static final int ERROR_DIALOG_REQUEST = 9001; 34 | 35 | //Firebase 36 | private FirebaseAuth.AuthStateListener mAuthListener; 37 | 38 | // widgets 39 | private EditText mEmail, mPassword; 40 | private ProgressBar mProgressBar; 41 | 42 | 43 | @Override 44 | protected void onCreate(Bundle savedInstanceState) { 45 | super.onCreate(savedInstanceState); 46 | setContentView(R.layout.activity_login); 47 | mEmail = (EditText) findViewById(R.id.email); 48 | mPassword = (EditText) findViewById(R.id.password); 49 | mProgressBar = (ProgressBar) findViewById(R.id.progressBar); 50 | 51 | setupFirebaseAuth(); 52 | if(servicesOK()){ 53 | init(); 54 | } 55 | hideSoftKeyboard(); 56 | 57 | } 58 | 59 | private void init(){ 60 | Button signIn = (Button) findViewById(R.id.email_sign_in_button); 61 | signIn.setOnClickListener(new View.OnClickListener() { 62 | @Override 63 | public void onClick(View view) { 64 | 65 | //check if the fields are filled out 66 | if(!isEmpty(mEmail.getText().toString()) 67 | && !isEmpty(mPassword.getText().toString())){ 68 | Log.d(TAG, "onClick: attempting to authenticate."); 69 | 70 | showDialog(); 71 | 72 | FirebaseAuth.getInstance().signInWithEmailAndPassword(mEmail.getText().toString(), 73 | mPassword.getText().toString()) 74 | .addOnCompleteListener(new OnCompleteListener() { 75 | @Override 76 | public void onComplete(@NonNull Task task) { 77 | 78 | hideDialog(); 79 | 80 | } 81 | }).addOnFailureListener(new OnFailureListener() { 82 | @Override 83 | public void onFailure(@NonNull Exception e) { 84 | Toast.makeText(LoginActivity.this, "Authentication Failed", Toast.LENGTH_SHORT).show(); 85 | hideDialog(); 86 | } 87 | }); 88 | }else{ 89 | Toast.makeText(LoginActivity.this, "You didn't fill in all the fields.", Toast.LENGTH_SHORT).show(); 90 | } 91 | } 92 | }); 93 | 94 | TextView register = (TextView) findViewById(R.id.link_register); 95 | register.setOnClickListener(new View.OnClickListener() { 96 | @Override 97 | public void onClick(View view) { 98 | Intent intent = new Intent(LoginActivity.this, RegisterActivity.class); 99 | startActivity(intent); 100 | } 101 | }); 102 | 103 | 104 | } 105 | 106 | 107 | public boolean servicesOK(){ 108 | Log.d(TAG, "servicesOK: Checking Google Services."); 109 | 110 | int isAvailable = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(LoginActivity.this); 111 | 112 | if(isAvailable == ConnectionResult.SUCCESS){ 113 | //everything is ok and the user can make mapping requests 114 | Log.d(TAG, "servicesOK: Play Services is OK"); 115 | return true; 116 | } 117 | else if(GoogleApiAvailability.getInstance().isUserResolvableError(isAvailable)){ 118 | //an error occured, but it's resolvable 119 | Log.d(TAG, "servicesOK: an error occured, but it's resolvable."); 120 | Dialog dialog = GoogleApiAvailability.getInstance().getErrorDialog(LoginActivity.this, isAvailable, ERROR_DIALOG_REQUEST); 121 | dialog.show(); 122 | } 123 | else{ 124 | Toast.makeText(this, "Can't connect to mapping services", Toast.LENGTH_SHORT).show(); 125 | } 126 | 127 | return false; 128 | } 129 | 130 | 131 | /** 132 | * Return true if the @param is null 133 | * @param string 134 | * @return 135 | */ 136 | private boolean isEmpty(String string){ 137 | return string.equals(""); 138 | } 139 | 140 | 141 | private void showDialog(){ 142 | mProgressBar.setVisibility(View.VISIBLE); 143 | 144 | } 145 | 146 | private void hideDialog(){ 147 | if(mProgressBar.getVisibility() == View.VISIBLE){ 148 | mProgressBar.setVisibility(View.INVISIBLE); 149 | } 150 | } 151 | 152 | private void hideSoftKeyboard(){ 153 | this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); 154 | } 155 | 156 | /* 157 | ----------------------------- Firebase setup --------------------------------- 158 | */ 159 | private void setupFirebaseAuth(){ 160 | Log.d(TAG, "setupFirebaseAuth: started."); 161 | 162 | mAuthListener = new FirebaseAuth.AuthStateListener() { 163 | @Override 164 | public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { 165 | FirebaseUser user = firebaseAuth.getCurrentUser(); 166 | if (user != null) { 167 | 168 | Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid()); 169 | Toast.makeText(LoginActivity.this, "Authenticated with: " + user.getEmail(), Toast.LENGTH_SHORT).show(); 170 | 171 | Intent intent = new Intent(LoginActivity.this, UserListActivity.class); 172 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 173 | 174 | //check for extras from FCM 175 | if (getIntent().getExtras() != null) { 176 | Log.d(TAG, "initFCM: found intent extras: " + getIntent().getExtras().toString()); 177 | for (String key : getIntent().getExtras().keySet()) { 178 | Object value = getIntent().getExtras().get(key); 179 | Log.d(TAG, "initFCM: Key: " + key + " Value: " + value); 180 | } 181 | String data = getIntent().getStringExtra("data"); 182 | Log.d(TAG, "initFCM: data: " + data); 183 | } 184 | startActivity(intent); 185 | finish(); 186 | 187 | 188 | } else { 189 | // User is signed out 190 | Log.d(TAG, "onAuthStateChanged:signed_out"); 191 | } 192 | // ... 193 | } 194 | }; 195 | } 196 | 197 | @Override 198 | public void onStart() { 199 | super.onStart(); 200 | FirebaseAuth.getInstance().addAuthStateListener(mAuthListener); 201 | } 202 | 203 | @Override 204 | public void onStop() { 205 | super.onStop(); 206 | if (mAuthListener != null) { 207 | FirebaseAuth.getInstance().removeAuthStateListener(mAuthListener); 208 | } 209 | } 210 | } 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | -------------------------------------------------------------------------------- /FirebaseDirectMessage/app/src/main/java/codingwithmitch/com/firebasedirectmessage/RegisterActivity.java: -------------------------------------------------------------------------------- 1 | package codingwithmitch.com.firebasedirectmessage; 2 | 3 | 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.support.annotation.NonNull; 7 | import android.support.annotation.Nullable; 8 | import android.support.v7.app.AppCompatActivity; 9 | import android.util.Log; 10 | import android.view.View; 11 | import android.view.WindowManager; 12 | import android.widget.Button; 13 | import android.widget.EditText; 14 | import android.widget.ProgressBar; 15 | import android.widget.Toast; 16 | 17 | import com.google.android.gms.tasks.OnCompleteListener; 18 | import com.google.android.gms.tasks.OnFailureListener; 19 | import com.google.android.gms.tasks.Task; 20 | import com.google.firebase.auth.AuthResult; 21 | import com.google.firebase.auth.FirebaseAuth; 22 | import com.google.firebase.auth.FirebaseUser; 23 | import com.google.firebase.database.FirebaseDatabase; 24 | 25 | import codingwithmitch.com.firebasedirectmessage.models.User; 26 | 27 | 28 | public class RegisterActivity extends AppCompatActivity { 29 | 30 | private static final String TAG = "RegisterActivity"; 31 | 32 | //widgets 33 | private EditText mEmail, mPassword, mConfirmPassword; 34 | private Button mRegister; 35 | private ProgressBar mProgressBar; 36 | 37 | 38 | @Override 39 | protected void onCreate(@Nullable Bundle savedInstanceState) { 40 | super.onCreate(savedInstanceState); 41 | setContentView(R.layout.activity_register); 42 | mEmail = (EditText) findViewById(R.id.input_email); 43 | mPassword = (EditText) findViewById(R.id.input_password); 44 | mConfirmPassword = (EditText) findViewById(R.id.input_confirm_password); 45 | mRegister = (Button) findViewById(R.id.btn_register); 46 | mProgressBar = (ProgressBar) findViewById(R.id.progressBar); 47 | 48 | mRegister.setOnClickListener(new View.OnClickListener() { 49 | @Override 50 | public void onClick(View view) { 51 | Log.d(TAG, "onClick: attempting to register."); 52 | 53 | //check for null valued EditText fields 54 | if(!isEmpty(mEmail.getText().toString()) 55 | && !isEmpty(mPassword.getText().toString()) 56 | && !isEmpty(mConfirmPassword.getText().toString())){ 57 | 58 | //check if passwords match 59 | if(doStringsMatch(mPassword.getText().toString(), mConfirmPassword.getText().toString())){ 60 | 61 | //Initiate registration task 62 | registerNewEmail(mEmail.getText().toString(), mPassword.getText().toString()); 63 | }else{ 64 | Toast.makeText(RegisterActivity.this, "Passwords do not Match", Toast.LENGTH_SHORT).show(); 65 | } 66 | 67 | 68 | }else{ 69 | Toast.makeText(RegisterActivity.this, "You must fill out all the fields", Toast.LENGTH_SHORT).show(); 70 | } 71 | } 72 | }); 73 | 74 | hideSoftKeyboard(); 75 | 76 | } 77 | 78 | 79 | /** 80 | * Register a new email and password to Firebase Authentication 81 | * @param email 82 | * @param password 83 | */ 84 | public void registerNewEmail(final String email, String password){ 85 | 86 | showDialog(); 87 | 88 | FirebaseAuth.getInstance().createUserWithEmailAndPassword(email, password) 89 | .addOnCompleteListener(new OnCompleteListener() { 90 | @Override 91 | public void onComplete(@NonNull Task task) { 92 | Log.d(TAG, "createUserWithEmail:onComplete:" + task.isSuccessful()); 93 | 94 | if (task.isSuccessful()){ 95 | Log.d(TAG, "onComplete: AuthState: " + FirebaseAuth.getInstance().getCurrentUser().getUid()); 96 | 97 | 98 | //insert some default data 99 | User user = new User(); 100 | user.setName(email.substring(0, email.indexOf("@"))); 101 | user.setUser_id(FirebaseAuth.getInstance().getCurrentUser().getUid()); 102 | FirebaseDatabase.getInstance().getReference() 103 | .child(getString(R.string.dbnode_users)) 104 | .child(FirebaseAuth.getInstance().getCurrentUser().getUid()) 105 | .setValue(user) 106 | .addOnCompleteListener(new OnCompleteListener() { 107 | @Override 108 | public void onComplete(@NonNull Task task) { 109 | FirebaseAuth.getInstance().signOut(); 110 | 111 | //redirect the user to the login screen 112 | redirectLoginScreen(); 113 | } 114 | }).addOnFailureListener(new OnFailureListener() { 115 | @Override 116 | public void onFailure(@NonNull Exception e) { 117 | Toast.makeText(RegisterActivity.this, "something went wrong.", Toast.LENGTH_SHORT).show(); 118 | FirebaseAuth.getInstance().signOut(); 119 | 120 | //redirect the user to the login screen 121 | redirectLoginScreen(); 122 | } 123 | }); 124 | 125 | } 126 | if (!task.isSuccessful()) { 127 | Toast.makeText(RegisterActivity.this, "Unable to Register", 128 | Toast.LENGTH_SHORT).show(); 129 | } 130 | hideDialog(); 131 | 132 | // ... 133 | } 134 | }); 135 | } 136 | 137 | 138 | /** 139 | * Redirects the user to the login screen 140 | */ 141 | private void redirectLoginScreen(){ 142 | Log.d(TAG, "redirectLoginScreen: redirecting to login screen."); 143 | 144 | Intent intent = new Intent(RegisterActivity.this, LoginActivity.class); 145 | startActivity(intent); 146 | finish(); 147 | } 148 | /** 149 | * Return true if @param 's1' matches @param 's2' 150 | * @param s1 151 | * @param s2 152 | * @return 153 | */ 154 | private boolean doStringsMatch(String s1, String s2){ 155 | return s1.equals(s2); 156 | } 157 | 158 | /** 159 | * Return true if the @param is null 160 | * @param string 161 | * @return 162 | */ 163 | private boolean isEmpty(String string){ 164 | return string.equals(""); 165 | } 166 | 167 | 168 | private void showDialog(){ 169 | mProgressBar.setVisibility(View.VISIBLE); 170 | 171 | } 172 | 173 | private void hideDialog(){ 174 | if(mProgressBar.getVisibility() == View.VISIBLE){ 175 | mProgressBar.setVisibility(View.INVISIBLE); 176 | } 177 | } 178 | 179 | private void hideSoftKeyboard(){ 180 | this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); 181 | } 182 | 183 | } 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | -------------------------------------------------------------------------------- /FirebaseDirectMessage/app/src/main/java/codingwithmitch/com/firebasedirectmessage/UserListActivity.java: -------------------------------------------------------------------------------- 1 | package codingwithmitch.com.firebasedirectmessage; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.annotation.NonNull; 6 | import android.support.annotation.Nullable; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.support.v7.widget.LinearLayoutManager; 9 | import android.support.v7.widget.RecyclerView; 10 | import android.util.Log; 11 | import android.view.Menu; 12 | import android.view.MenuItem; 13 | 14 | import com.google.firebase.auth.FirebaseAuth; 15 | import com.google.firebase.auth.FirebaseUser; 16 | import com.google.firebase.database.DataSnapshot; 17 | import com.google.firebase.database.DatabaseError; 18 | import com.google.firebase.database.DatabaseReference; 19 | import com.google.firebase.database.FirebaseDatabase; 20 | import com.google.firebase.database.Query; 21 | import com.google.firebase.database.ValueEventListener; 22 | import com.google.firebase.iid.FirebaseInstanceId; 23 | 24 | import java.util.ArrayList; 25 | 26 | import codingwithmitch.com.firebasedirectmessage.models.User; 27 | import codingwithmitch.com.firebasedirectmessage.utility.MessageDialog; 28 | import codingwithmitch.com.firebasedirectmessage.utility.UserAdapter; 29 | 30 | 31 | public class UserListActivity extends AppCompatActivity { 32 | 33 | private static final String TAG = "UserListActivity"; 34 | 35 | //firebase 36 | private FirebaseAuth.AuthStateListener mAuthListener; 37 | 38 | //widgets 39 | private RecyclerView mRecyclerView; 40 | 41 | //vars 42 | private ArrayList mUsers; 43 | private UserAdapter mUserAdapter; 44 | 45 | 46 | @Override 47 | protected void onCreate(@Nullable Bundle savedInstanceState) { 48 | super.onCreate(savedInstanceState); 49 | setContentView(R.layout.activity_userlist); 50 | mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView); 51 | 52 | setupFirebaseAuth(); 53 | setupUserList(); 54 | getUserList(); 55 | initFCM(); 56 | } 57 | 58 | private void initFCM(){ 59 | String token = FirebaseInstanceId.getInstance().getToken(); 60 | Log.d(TAG, "initFCM: token: " + token); 61 | sendRegistrationToServer(token); 62 | 63 | } 64 | public void openMessageDialog(String userId){ 65 | Log.d(TAG, "openMessageDialog: opening a dialog to send a new message"); 66 | MessageDialog dialog = new MessageDialog(); 67 | 68 | Bundle bundle = new Bundle(); 69 | bundle.putString(getString(R.string.intent_user_id), userId); 70 | dialog.setArguments(bundle); 71 | dialog.show(getSupportFragmentManager(), getString(R.string.dialog_message)); 72 | } 73 | 74 | private void getUserList() throws NullPointerException{ 75 | Log.d(TAG, "getUserList: getting a list of all users"); 76 | DatabaseReference reference = FirebaseDatabase.getInstance().getReference(); 77 | 78 | Query query = reference.child(getString(R.string.dbnode_users)); 79 | 80 | query.addListenerForSingleValueEvent(new ValueEventListener() { 81 | @Override 82 | public void onDataChange(DataSnapshot dataSnapshot) { 83 | 84 | for(DataSnapshot snapshot: dataSnapshot.getChildren()){ 85 | User user = snapshot.getValue(User.class); 86 | Log.d(TAG, "onDataChange: found a user: " + user.getName()); 87 | mUsers.add(user); 88 | } 89 | mUserAdapter.notifyDataSetChanged(); 90 | } 91 | 92 | @Override 93 | public void onCancelled(DatabaseError databaseError) { 94 | 95 | } 96 | }); 97 | } 98 | 99 | /** 100 | * Persist token to third-party servers. 101 | * 102 | * Modify this method to associate the user's FCM InstanceID token with any server-side account 103 | * maintained by your application. 104 | * 105 | * @param token The new token. 106 | */ 107 | private void sendRegistrationToServer(String token) { 108 | Log.d(TAG, "sendRegistrationToServer: sending token to server: " + token); 109 | DatabaseReference reference = FirebaseDatabase.getInstance().getReference(); 110 | reference.child(getString(R.string.dbnode_users)) 111 | .child(FirebaseAuth.getInstance().getCurrentUser().getUid()) 112 | .child(getString(R.string.field_messaging_token)) 113 | .setValue(token); 114 | } 115 | 116 | private void setupUserList(){ 117 | mUsers = new ArrayList<>(); 118 | mUserAdapter = new UserAdapter(UserListActivity.this, mUsers); 119 | RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext()); 120 | mRecyclerView.setLayoutManager(layoutManager); 121 | mRecyclerView.setAdapter(mUserAdapter); 122 | } 123 | 124 | private void signOut(){ 125 | Log.d(TAG, "signOut: signing out user"); 126 | FirebaseAuth.getInstance().signOut(); 127 | } 128 | 129 | @Override 130 | public boolean onCreateOptionsMenu(Menu menu) { 131 | getMenuInflater().inflate(R.menu.menu, menu); 132 | 133 | return true; 134 | } 135 | 136 | @Override 137 | public boolean onOptionsItemSelected(MenuItem item) { 138 | switch(item.getItemId()){ 139 | case R.id.sign_out: 140 | signOut(); 141 | return true; 142 | default: 143 | return super.onOptionsItemSelected(item); 144 | } 145 | } 146 | 147 | 148 | /* 149 | ----------------------------- Firebase setup --------------------------------- 150 | */ 151 | private void setupFirebaseAuth(){ 152 | Log.d(TAG, "setupFirebaseAuth: started."); 153 | 154 | mAuthListener = new FirebaseAuth.AuthStateListener() { 155 | @Override 156 | public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { 157 | FirebaseUser user = firebaseAuth.getCurrentUser(); 158 | if (user != null) { 159 | 160 | Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid()); 161 | 162 | } else { 163 | Log.d(TAG, "onAuthStateChanged:signed_out"); 164 | Intent intent = new Intent(UserListActivity.this, LoginActivity.class); 165 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 166 | startActivity(intent); 167 | finish(); 168 | } 169 | // ... 170 | } 171 | }; 172 | } 173 | 174 | @Override 175 | public void onStart() { 176 | super.onStart(); 177 | FirebaseAuth.getInstance().addAuthStateListener(mAuthListener); 178 | 179 | } 180 | 181 | @Override 182 | public void onStop() { 183 | super.onStop(); 184 | if (mAuthListener != null) { 185 | FirebaseAuth.getInstance().removeAuthStateListener(mAuthListener); 186 | } 187 | 188 | } 189 | } 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | -------------------------------------------------------------------------------- /FirebaseDirectMessage/app/src/main/java/codingwithmitch/com/firebasedirectmessage/models/Message.java: -------------------------------------------------------------------------------- 1 | package codingwithmitch.com.firebasedirectmessage.models; 2 | 3 | /** 4 | * Created by User on 11/11/2017. 5 | */ 6 | 7 | public class Message { 8 | 9 | private String message; 10 | private String user_id; 11 | private String timestamp; 12 | 13 | public Message(String message, String user_id, String timestamp) { 14 | this.message = message; 15 | this.user_id = user_id; 16 | this.timestamp = timestamp; 17 | } 18 | 19 | public Message() { 20 | 21 | } 22 | 23 | public String getMessage() { 24 | return message; 25 | } 26 | 27 | public void setMessage(String message) { 28 | this.message = message; 29 | } 30 | 31 | public String getUser_id() { 32 | return user_id; 33 | } 34 | 35 | public void setUser_id(String user_id) { 36 | this.user_id = user_id; 37 | } 38 | 39 | public String getTimestamp() { 40 | return timestamp; 41 | } 42 | 43 | public void setTimestamp(String timestamp) { 44 | this.timestamp = timestamp; 45 | } 46 | 47 | @Override 48 | public String toString() { 49 | return "Message{" + 50 | "message='" + message + '\'' + 51 | ", user_id='" + user_id + '\'' + 52 | ", timestamp='" + timestamp + '\'' + 53 | '}'; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /FirebaseDirectMessage/app/src/main/java/codingwithmitch/com/firebasedirectmessage/models/User.java: -------------------------------------------------------------------------------- 1 | package codingwithmitch.com.firebasedirectmessage.models; 2 | 3 | 4 | public class User { 5 | 6 | private String name; 7 | private String user_id; 8 | 9 | public User(String name, String user_id) { 10 | this.name = name; 11 | this.user_id = user_id; 12 | } 13 | 14 | public User() { 15 | 16 | } 17 | 18 | public String getName() { 19 | return name; 20 | } 21 | 22 | public void setName(String name) { 23 | this.name = name; 24 | } 25 | 26 | public String getUser_id() { 27 | return user_id; 28 | } 29 | 30 | public void setUser_id(String user_id) { 31 | this.user_id = user_id; 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | return "User{" + 37 | "name='" + name + '\'' + 38 | ", user_id='" + user_id + '\'' + 39 | '}'; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /FirebaseDirectMessage/app/src/main/java/codingwithmitch/com/firebasedirectmessage/utility/MessageDialog.java: -------------------------------------------------------------------------------- 1 | package codingwithmitch.com.firebasedirectmessage.utility; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v4.app.DialogFragment; 6 | import android.util.Log; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.Button; 11 | import android.widget.EditText; 12 | import android.widget.Toast; 13 | 14 | import com.google.firebase.auth.FirebaseAuth; 15 | import com.google.firebase.database.DatabaseReference; 16 | import com.google.firebase.database.FirebaseDatabase; 17 | 18 | import java.text.SimpleDateFormat; 19 | import java.util.Date; 20 | import java.util.Locale; 21 | import java.util.TimeZone; 22 | 23 | import codingwithmitch.com.firebasedirectmessage.R; 24 | import codingwithmitch.com.firebasedirectmessage.models.Message; 25 | 26 | /** 27 | * Created by User on 11/11/2017. 28 | */ 29 | 30 | public class MessageDialog extends DialogFragment { 31 | 32 | private static final String TAG = "MessageDialog"; 33 | 34 | //create a new bundle and set the arguments to avoid a null pointer 35 | public MessageDialog(){ 36 | super(); 37 | setArguments(new Bundle()); 38 | } 39 | 40 | 41 | //widgets 42 | EditText mMessage; 43 | 44 | //vars 45 | private String mUserId; 46 | 47 | 48 | @Override 49 | public void onCreate(@Nullable Bundle savedInstanceState) { 50 | super.onCreate(savedInstanceState); 51 | Log.d(TAG, "onCreate: started."); 52 | mUserId = getArguments().getString(getString(R.string.intent_user_id)); 53 | } 54 | 55 | @Nullable 56 | @Override 57 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 58 | View view = inflater.inflate(R.layout.dialog_message, container, false); 59 | mMessage = (EditText) view.findViewById(R.id.message); 60 | 61 | Button send = (Button) view.findViewById(R.id.send); 62 | send.setOnClickListener(new View.OnClickListener() { 63 | @Override 64 | public void onClick(View v) { 65 | Log.d(TAG, "onClick: sending a new message"); 66 | 67 | DatabaseReference reference = FirebaseDatabase.getInstance().getReference(); 68 | if(!mMessage.getText().toString().equals("")){ 69 | 70 | //create the new message 71 | Message message = new Message(); 72 | message.setUser_id(FirebaseAuth.getInstance().getCurrentUser().getUid()); 73 | message.setMessage(mMessage.getText().toString()); 74 | message.setTimestamp(getTimestamp()); 75 | 76 | //insert the new message 77 | reference 78 | .child(getString(R.string.dbnode_messages)) 79 | .child(mUserId) 80 | .child(reference.push().getKey()) 81 | .setValue(message); 82 | getDialog().dismiss(); 83 | Toast.makeText(getActivity(), "message sent", Toast.LENGTH_SHORT).show(); 84 | }else{ 85 | Toast.makeText(getActivity(), "enter a message", Toast.LENGTH_SHORT).show(); 86 | } 87 | 88 | } 89 | }); 90 | 91 | return view; 92 | } 93 | 94 | /** 95 | * Return the current timestamp in the form of a string 96 | * @return 97 | */ 98 | private String getTimestamp(){ 99 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); 100 | sdf.setTimeZone(TimeZone.getTimeZone("Canada/Pacific")); 101 | return sdf.format(new Date()); 102 | } 103 | 104 | 105 | } 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /FirebaseDirectMessage/app/src/main/java/codingwithmitch/com/firebasedirectmessage/utility/MyFirebaseInstanceIDService.java: -------------------------------------------------------------------------------- 1 | package codingwithmitch.com.firebasedirectmessage.utility; 2 | 3 | import android.util.Log; 4 | 5 | import com.google.firebase.auth.FirebaseAuth; 6 | import com.google.firebase.database.DatabaseReference; 7 | import com.google.firebase.database.FirebaseDatabase; 8 | import com.google.firebase.iid.FirebaseInstanceId; 9 | import com.google.firebase.iid.FirebaseInstanceIdService; 10 | 11 | import codingwithmitch.com.firebasedirectmessage.R; 12 | 13 | 14 | public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService { 15 | private static final String TAG = "MyFirebaseIIDService"; 16 | 17 | /** 18 | * Called if InstanceID token is updated. This may occur if the security of 19 | * the previous token had been compromised. Note that this is called when the InstanceID token 20 | * is initially generated so this is where you would retrieve the token. 21 | */ 22 | @Override 23 | public void onTokenRefresh() { 24 | // Get updated InstanceID token. 25 | String refreshedToken = FirebaseInstanceId.getInstance().getToken(); 26 | Log.d(TAG, "Refreshed token: " + refreshedToken); 27 | 28 | sendRegistrationToServer(refreshedToken); 29 | } 30 | 31 | 32 | /** 33 | * Persist token to third-party servers. 34 | * 35 | * Modify this method to associate the user's FCM InstanceID token with any server-side account 36 | * maintained by your application. 37 | * 38 | * @param token The new token. 39 | */ 40 | private void sendRegistrationToServer(String token) { 41 | Log.d(TAG, "sendRegistrationToServer: sending token to server: " + token); 42 | DatabaseReference reference = FirebaseDatabase.getInstance().getReference(); 43 | reference.child(getString(R.string.dbnode_users)) 44 | .child(FirebaseAuth.getInstance().getCurrentUser().getUid()) 45 | .child(getString(R.string.field_messaging_token)) 46 | .setValue(token); 47 | } 48 | } 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /FirebaseDirectMessage/app/src/main/java/codingwithmitch/com/firebasedirectmessage/utility/MyFirebaseMessagingService.java: -------------------------------------------------------------------------------- 1 | package codingwithmitch.com.firebasedirectmessage.utility; 2 | 3 | 4 | import android.app.NotificationManager; 5 | import android.app.PendingIntent; 6 | import android.content.Context; 7 | import android.content.Intent; 8 | import android.graphics.BitmapFactory; 9 | import android.media.RingtoneManager; 10 | import android.support.v4.app.NotificationCompat; 11 | import android.util.Log; 12 | import com.google.firebase.messaging.FirebaseMessagingService; 13 | import com.google.firebase.messaging.RemoteMessage; 14 | 15 | import codingwithmitch.com.firebasedirectmessage.R; 16 | import codingwithmitch.com.firebasedirectmessage.UserListActivity; 17 | 18 | 19 | public class MyFirebaseMessagingService extends FirebaseMessagingService { 20 | 21 | private static final String TAG = "MyFirebaseMsgService"; 22 | private static final int BROADCAST_NOTIFICATION_ID = 1; 23 | 24 | @Override 25 | public void onDeletedMessages() { 26 | super.onDeletedMessages(); 27 | } 28 | 29 | /** 30 | * Called when message is received. 31 | * 32 | * @param remoteMessage Object representing the message received from Firebase Cloud Messaging. 33 | */ 34 | @Override 35 | public void onMessageReceived(RemoteMessage remoteMessage) { 36 | 37 | String notificationBody = ""; 38 | String notificationTitle = ""; 39 | String notificationData = ""; 40 | try{ 41 | notificationData = remoteMessage.getData().toString(); 42 | notificationTitle = remoteMessage.getNotification().getTitle(); 43 | notificationBody = remoteMessage.getNotification().getBody(); 44 | }catch (NullPointerException e){ 45 | Log.e(TAG, "onMessageReceived: NullPointerException: " + e.getMessage() ); 46 | } 47 | Log.d(TAG, "onMessageReceived: data: " + notificationData); 48 | Log.d(TAG, "onMessageReceived: notification body: " + notificationBody); 49 | Log.d(TAG, "onMessageReceived: notification title: " + notificationTitle); 50 | 51 | 52 | String dataType = remoteMessage.getData().get(getString(R.string.data_type)); 53 | if(dataType.equals(getString(R.string.direct_message))){ 54 | Log.d(TAG, "onMessageReceived: new incoming message."); 55 | String title = remoteMessage.getData().get(getString(R.string.data_title)); 56 | String message = remoteMessage.getData().get(getString(R.string.data_message)); 57 | String messageId = remoteMessage.getData().get(getString(R.string.data_message_id)); 58 | sendMessageNotification(title, message, messageId); 59 | } 60 | } 61 | 62 | /** 63 | * Build a push notification for a chat message 64 | * @param title 65 | * @param message 66 | */ 67 | private void sendMessageNotification(String title, String message, String messageId){ 68 | Log.d(TAG, "sendChatmessageNotification: building a chatmessage notification"); 69 | 70 | //get the notification id 71 | int notificationId = buildNotificationId(messageId); 72 | 73 | // Instantiate a Builder object. 74 | NotificationCompat.Builder builder = new NotificationCompat.Builder(this, 75 | getString(R.string.default_notification_channel_id)); 76 | // Creates an Intent for the Activity 77 | Intent pendingIntent = new Intent(this, UserListActivity.class); 78 | // Sets the Activity to start in a new, empty task 79 | pendingIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 80 | // Creates the PendingIntent 81 | PendingIntent notifyPendingIntent = 82 | PendingIntent.getActivity( 83 | this, 84 | 0, 85 | pendingIntent, 86 | PendingIntent.FLAG_UPDATE_CURRENT 87 | ); 88 | 89 | //add properties to the builder 90 | builder.setSmallIcon(R.drawable.ic_android_blue) 91 | .setLargeIcon(BitmapFactory.decodeResource(getApplicationContext().getResources(), 92 | R.drawable.ic_android_blue)) 93 | .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)) 94 | .setContentTitle(title) 95 | .setColor(getColor(R.color.blue1)) 96 | .setAutoCancel(true) 97 | //.setSubText(message) 98 | .setStyle(new NotificationCompat.BigTextStyle().bigText(message)) 99 | .setOnlyAlertOnce(true); 100 | 101 | builder.setContentIntent(notifyPendingIntent); 102 | NotificationManager mNotificationManager = 103 | (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 104 | 105 | mNotificationManager.notify(notificationId, builder.build()); 106 | 107 | } 108 | 109 | 110 | private int buildNotificationId(String id){ 111 | Log.d(TAG, "buildNotificationId: building a notification id."); 112 | 113 | int notificationId = 0; 114 | for(int i = 0; i < 9; i++){ 115 | notificationId = notificationId + id.charAt(0); 116 | } 117 | Log.d(TAG, "buildNotificationId: id: " + id); 118 | Log.d(TAG, "buildNotificationId: notification id:" + notificationId); 119 | return notificationId; 120 | } 121 | 122 | } 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /FirebaseDirectMessage/app/src/main/java/codingwithmitch/com/firebasedirectmessage/utility/UserAdapter.java: -------------------------------------------------------------------------------- 1 | package codingwithmitch.com.firebasedirectmessage.utility; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.util.Log; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.ImageView; 10 | import android.widget.TextView; 11 | 12 | import java.util.ArrayList; 13 | 14 | import codingwithmitch.com.firebasedirectmessage.R; 15 | import codingwithmitch.com.firebasedirectmessage.UserListActivity; 16 | import codingwithmitch.com.firebasedirectmessage.models.User; 17 | 18 | 19 | public class UserAdapter extends RecyclerView.Adapter{ 20 | 21 | private static final String TAG = "EmployeesAdapter"; 22 | 23 | private ArrayList mUsers; 24 | private Context mContext; 25 | 26 | public class ViewHolder extends RecyclerView.ViewHolder{ 27 | 28 | public TextView name; 29 | 30 | public ViewHolder(View itemView) { 31 | super(itemView); 32 | name = (TextView) itemView.findViewById(R.id.name); 33 | 34 | itemView.setOnClickListener(new View.OnClickListener() { 35 | @Override 36 | public void onClick(View v) { 37 | Log.d(TAG, "onClick: selected employee: " + mUsers.get(getAdapterPosition())); 38 | 39 | //open a dialog for inserting a message into the database 40 | ((UserListActivity)mContext).openMessageDialog(mUsers.get(getAdapterPosition()).getUser_id()); 41 | } 42 | }); 43 | } 44 | } 45 | 46 | public UserAdapter(Context context, ArrayList users) { 47 | mUsers = users; 48 | mContext = context; 49 | } 50 | 51 | @Override 52 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 53 | Context context = parent.getContext(); 54 | LayoutInflater inflater = LayoutInflater.from(context); 55 | 56 | //inflate the custom layout 57 | View view = inflater.inflate(R.layout.layout_user_listitem, parent, false); 58 | 59 | //return a new holder instance 60 | return new ViewHolder(view); 61 | } 62 | 63 | @Override 64 | public void onBindViewHolder(ViewHolder holder, int position) throws NullPointerException{ 65 | holder.name.setText(mUsers.get(position).getName()); 66 | } 67 | 68 | 69 | @Override 70 | public int getItemCount() { 71 | return mUsers.size(); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /FirebaseDirectMessage/app/src/main/res/drawable-hdpi/ic_android.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FirebaseDirectMessage/6fc6a500be39ddbaf5fd2dfa99e22563d401a626/FirebaseDirectMessage/app/src/main/res/drawable-hdpi/ic_android.png -------------------------------------------------------------------------------- /FirebaseDirectMessage/app/src/main/res/drawable-hdpi/ic_android_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FirebaseDirectMessage/6fc6a500be39ddbaf5fd2dfa99e22563d401a626/FirebaseDirectMessage/app/src/main/res/drawable-hdpi/ic_android_blue.png -------------------------------------------------------------------------------- /FirebaseDirectMessage/app/src/main/res/drawable-mdpi/ic_android.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FirebaseDirectMessage/6fc6a500be39ddbaf5fd2dfa99e22563d401a626/FirebaseDirectMessage/app/src/main/res/drawable-mdpi/ic_android.png -------------------------------------------------------------------------------- /FirebaseDirectMessage/app/src/main/res/drawable-mdpi/ic_android_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FirebaseDirectMessage/6fc6a500be39ddbaf5fd2dfa99e22563d401a626/FirebaseDirectMessage/app/src/main/res/drawable-mdpi/ic_android_blue.png -------------------------------------------------------------------------------- /FirebaseDirectMessage/app/src/main/res/drawable-xhdpi/ic_android.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FirebaseDirectMessage/6fc6a500be39ddbaf5fd2dfa99e22563d401a626/FirebaseDirectMessage/app/src/main/res/drawable-xhdpi/ic_android.png -------------------------------------------------------------------------------- /FirebaseDirectMessage/app/src/main/res/drawable-xhdpi/ic_android_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FirebaseDirectMessage/6fc6a500be39ddbaf5fd2dfa99e22563d401a626/FirebaseDirectMessage/app/src/main/res/drawable-xhdpi/ic_android_blue.png -------------------------------------------------------------------------------- /FirebaseDirectMessage/app/src/main/res/drawable-xxhdpi/ic_android.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FirebaseDirectMessage/6fc6a500be39ddbaf5fd2dfa99e22563d401a626/FirebaseDirectMessage/app/src/main/res/drawable-xxhdpi/ic_android.png -------------------------------------------------------------------------------- /FirebaseDirectMessage/app/src/main/res/drawable-xxhdpi/ic_android_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchtabian/FirebaseDirectMessage/6fc6a500be39ddbaf5fd2dfa99e22563d401a626/FirebaseDirectMessage/app/src/main/res/drawable-xxhdpi/ic_android_blue.png -------------------------------------------------------------------------------- /FirebaseDirectMessage/app/src/main/res/layout/activity_login.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 11 | 12 | 19 | 20 | 21 | 22 | 30 | 31 | 32 | 33 | 45 | 46 |