Last active
January 21, 2025 16:18
Revisions
-
puf revised this gist
Aug 1, 2016 . 1 changed file with 34 additions and 0 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,34 @@ apply plugin: 'com.android.application' android { compileSdkVersion 24 buildToolsVersion '24' defaultConfig { applicationId "com.google.firebase.zerotoapp" minSdkVersion 16 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:24.0.0' compile 'com.android.support:design:24.0.0' compile 'com.android.support:recyclerview-v7:24.0.0' compile 'com.google.firebase:firebase-database:9.2.1' compile 'com.google.firebase:firebase-auth:9.2.1' compile 'com.google.firebase:firebase-storage:9.2.1' compile 'com.github.bumptech.glide:glide:3.7.0' compile 'com.firebaseui:firebase-ui-auth:0.4.3' } apply plugin: 'com.google.gms.google-services' -
puf revised this gist
Jun 2, 2016 . 1 changed file with 95 additions and 0 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,95 @@ <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.google.firebase.zerotoapp.MainActivity"> <RelativeLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/header" android:gravity="end"> <ImageView android:layout_width="36dp" android:layout_height="36dp" android:background="@drawable/ic_account_box_black_24dp" android:id="@+id/userIcon" android:foregroundGravity="center" android:layout_alignParentStart="true" android:layout_alignParentLeft="true" /> <TextView android:layout_width="141dp" android:layout_height="wrap_content" android:id="@+id/usernameTxt" android:layout_toRightOf="@+id/userIcon" android:layout_alignTop="@+id/userIcon" android:layout_alignBottom="@+id/userIcon" android:gravity="center_vertical" tools:text="Username" android:layout_weight="0" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Sign in" android:id="@+id/loginBtn" android:layout_alignParentEnd="true" android:layout_alignParentRight="true" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Sign out" android:id="@+id/logoutBtn" android:layout_alignParentEnd="true" android:layout_alignParentRight="true" /> </RelativeLayout> <android.support.v7.widget.RecyclerView android:id="@+id/messagesList" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" tools:listitem="@android:layout/two_line_list_item" android:layout_above="@+id/footer" android:layout_below="@+id/header" /> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:id="@+id/footer"> <ImageButton android:layout_width="36dp" android:layout_height="36dp" android:id="@+id/imageBtn" android:background="@android:drawable/ic_menu_gallery" /> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/messageTxt" android:layout_gravity="bottom" android:layout_weight="1" android:inputType="textShortMessage|textAutoCorrect" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Send" android:id="@+id/sendBtn" android:layout_gravity="bottom" /> </LinearLayout> </RelativeLayout> -
puf revised this gist
May 26, 2016 . 1 changed file with 60 additions and 2 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -104,22 +104,80 @@ public void onItemRangeInserted(int positionStart, int itemCount) { messagesList.smoothScrollToPosition(adapter.getItemCount()); } }); // Get the Firebase app and all primitives we'll use app = FirebaseApp.getInstance(); database = FirebaseDatabase.getInstance(app); auth = FirebaseAuth.getInstance(app); storage = FirebaseStorage.getInstance(app); // Get a reference to our chat "room" in the database databaseRef = database.getReference("chat"); sendBtn.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { ChatMessage chat = new ChatMessage(username, messageTxt.getText().toString()); // Push the chat message to the database databaseRef.push().setValue(chat); messageTxt.setText(""); } }); // Listen for when child nodes get added to the collection databaseRef.addChildEventListener(new ChildEventListener() { public void onChildAdded(DataSnapshot snapshot, String s) { // Get the chat message from the snapshot and add it to the UI ChatMessage chat = snapshot.getValue(ChatMessage.class); adapter.addMessage(chat); } public void onChildChanged(DataSnapshot dataSnapshot, String s) { } public void onChildRemoved(DataSnapshot dataSnapshot) { } public void onChildMoved(DataSnapshot dataSnapshot, String s) { } public void onCancelled(DatabaseError databaseError) { } }); // When the user has entered credentials in the login dialog LoginDialog.onCredentials(new OnSuccessListener<LoginDialog.EmailPasswordResult>() { public void onSuccess(LoginDialog.EmailPasswordResult result) { // Sign the user in with the email address and password they entered auth.signInWithEmailAndPassword(result.email, result.password); } }); // When the user signs in or out, update the username we keep for them auth.addAuthStateListener(new FirebaseAuth.AuthStateListener() { public void onAuthStateChanged(FirebaseAuth firebaseAuth) { if (firebaseAuth.getCurrentUser() != null) { // User signed in, set their email address as the user name setUsername(firebaseAuth.getCurrentUser().getEmail()); } else { // User signed out, set a default username setUsername("Android"); } } }); } public void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == RC_PHOTO_PICKER && resultCode == RESULT_OK) { Uri selectedImageUri = data.getData(); // Get a reference to the location where we'll store our photos storageRef = storage.getReference("chat_photos"); // Get a reference to store file at chat_photos/<FILENAME> final StorageReference photoRef = storageRef.child(selectedImageUri.getLastPathSegment()); // Upload file to Firebase Storage photoRef.putFile(selectedImageUri) .addOnSuccessListener(this, new OnSuccessListener<UploadTask.TaskSnapshot>() { public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { // When the image has successfully uploaded, we get its download URL Uri downloadUrl = taskSnapshot.getDownloadUrl(); // Set the download URL to the message box, so that the user can send it to the database messageTxt.setText(downloadUrl.toString()); } }); } } } -
puf created this gist
May 21, 2016 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,14 @@ package com.google.firebase.zerotoapp; public class ChatMessage { public String name; public String message; public ChatMessage() { } public ChatMessage(String name, String message) { this.name = name; this.message = message; } } 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,40 @@ package com.google.firebase.zerotoapp; import android.app.Activity; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.ViewGroup; import java.util.ArrayList; import java.util.List; public class ChatMessageAdapter extends RecyclerView.Adapter<ChatMessageViewHolder> { private static final String TAG = "ChatMessageAdapter"; private final Activity activity; List<ChatMessage> messages = new ArrayList<>(); public ChatMessageAdapter(Activity activity) { this.activity = activity; } public void addMessage(ChatMessage chat) { messages.add(chat); notifyItemInserted(messages.size()); } @Override public ChatMessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return new ChatMessageViewHolder(activity, activity.getLayoutInflater().inflate(android.R.layout.two_line_list_item, parent, false)); } @Override public void onBindViewHolder(ChatMessageViewHolder holder, int position) { holder.bind(messages.get(position)); } @Override public int getItemCount() { return messages.size(); } } 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,45 @@ package com.google.firebase.zerotoapp; import android.app.Activity; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import com.bumptech.glide.Glide; public class ChatMessageViewHolder extends RecyclerView.ViewHolder { private static final String TAG = "ChatMessageViewHolder"; private final Activity activity; TextView name, message; ImageView image; public ChatMessageViewHolder(Activity activity, View itemView) { super(itemView); this.activity = activity; name = (TextView) itemView.findViewById(android.R.id.text1); message = (TextView) itemView.findViewById(android.R.id.text2); image= new ImageView(activity); ((ViewGroup)itemView).addView(image); } public void bind(ChatMessage chat) { name.setText(chat.name); if (chat.message.startsWith("https://firebasestorage.googleapis.com/") || chat.message.startsWith("content://")) { message.setVisibility(View.INVISIBLE); image.setVisibility(View.VISIBLE); Glide.with(activity) .load(chat.message) .into(image); } else { message.setVisibility(View.VISIBLE); image.setVisibility(View.GONE); message.setText(chat.message); } } } 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,94 @@ package com.google.firebase.zerotoapp; import android.app.Activity; import android.content.DialogInterface; import android.support.v7.app.AlertDialog; import android.text.InputType; import android.widget.EditText; import android.widget.LinearLayout; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.OnSuccessListener; import com.google.android.gms.tasks.Task; import com.google.firebase.FirebaseApp; import com.google.firebase.auth.AuthResult; import com.google.firebase.auth.FirebaseAuth; import java.util.ArrayList; import java.util.List; public class LoginDialog { private static final String TAG = "LoginDialog"; static List<OnSuccessListener<EmailPasswordResult>> callbacks = new ArrayList<>(); public static void onCredentials(final OnSuccessListener<EmailPasswordResult> callback) { callbacks.add(callback); } public static class EmailPasswordResult { public String email; public String password; public EmailPasswordResult() { } public EmailPasswordResult(String email, String password) { this.email = email; this.password = password; } } public static void showLoginPrompt(final Activity activity, final FirebaseApp app) { showLoginPrompt(activity, app, null); } public static void showLoginPrompt(final Activity activity, final FirebaseApp app, final OnSuccessListener<EmailPasswordResult> callback) { AlertDialog.Builder builder = new AlertDialog.Builder(activity); builder.setTitle("What's your username"); LinearLayout parent = new LinearLayout(activity); parent.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); parent.setOrientation(LinearLayout.VERTICAL); final EditText email = new EditText(activity); email.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS); email.setHint("User name"); parent.addView(email); final EditText password = new EditText(activity); password.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); password.setHint("Password"); parent.addView(password); builder.setView(parent); builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { FirebaseAuth.getInstance(app).createUserWithEmailAndPassword(email.getText().toString(), password.getText().toString()) .addOnCompleteListener(activity, new OnCompleteListener<AuthResult>() { public void onComplete(Task<AuthResult> task) { EmailPasswordResult result = new EmailPasswordResult(email.getText().toString(), password.getText().toString()); if (callback != null) { callback.onSuccess(result); } else { for (OnSuccessListener<EmailPasswordResult> callback: callbacks){ callback.onSuccess(result); } } } }); dialog.dismiss(); } }); builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }); builder.show(); } } 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,125 @@ package com.google.firebase.zerotoapp; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageButton; import android.widget.TextView; import com.google.android.gms.tasks.OnSuccessListener; import com.google.firebase.FirebaseApp; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.database.DatabaseReference; import com.google.firebase.database.FirebaseDatabase; import com.google.firebase.storage.FirebaseStorage; import com.google.firebase.storage.StorageReference; public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; static final int RC_PHOTO_PICKER = 1; private Button sendBtn; private EditText messageTxt; private RecyclerView messagesList; private ChatMessageAdapter adapter; private ImageButton imageBtn; private TextView usernameTxt; private View loginBtn; private View logoutBtn; private FirebaseApp app; private FirebaseDatabase database; private FirebaseAuth auth; private FirebaseStorage storage; private DatabaseReference databaseRef; private StorageReference storageRef; private String username; private void setUsername(String username) { Log.d(TAG, "setUsername("+String.valueOf(username)+")"); if (username == null) { username = "Android"; } boolean isLoggedIn = !username.equals("Android"); this.username = username; this.usernameTxt.setText(username); this.logoutBtn.setVisibility(isLoggedIn ? View.VISIBLE : View.GONE); this.loginBtn .setVisibility(isLoggedIn ? View.GONE : View.VISIBLE); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sendBtn = (Button) findViewById(R.id.sendBtn); messageTxt = (EditText) findViewById(R.id.messageTxt); messagesList = (RecyclerView) findViewById(R.id.messagesList); imageBtn = (ImageButton) findViewById(R.id.imageBtn); loginBtn = findViewById(R.id.loginBtn); logoutBtn = findViewById(R.id.logoutBtn); usernameTxt = (TextView) findViewById(R.id.usernameTxt); setUsername("Android"); LinearLayoutManager layoutManager = new LinearLayoutManager(this); messagesList.setHasFixedSize(false); messagesList.setLayoutManager(layoutManager); // Show an image picker when the user wants to upload an imasge imageBtn.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { 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); } }); // Show a popup when the user asks to sign in loginBtn.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { LoginDialog.showLoginPrompt(MainActivity.this, app); } }); // Allow the user to sign out logoutBtn.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { auth.signOut(); } }); adapter = new ChatMessageAdapter(this); messagesList.setAdapter(adapter); adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() { public void onItemRangeInserted(int positionStart, int itemCount) { messagesList.smoothScrollToPosition(adapter.getItemCount()); } }); sendBtn.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { ChatMessage chat = new ChatMessage(username, messageTxt.getText().toString()); adapter.addMessage(chat); messageTxt.setText(""); } }); } public void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == RC_PHOTO_PICKER && resultCode == RESULT_OK) { Uri selectedImageUri = data.getData(); messageTxt.setText(selectedImageUri.toString()); } } }