Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e2aa484
reauthentication wip
Feb 7, 2017
4e6bd2a
clean up some lint errors
Feb 9, 2017
096c666
Review feedback part 1
Feb 10, 2017
4b5c4f8
Review feedback part 2
Feb 16, 2017
ab4a995
Use the native cancel string
Feb 16, 2017
50245ab
fix smartlock disabling in reauth
Feb 17, 2017
4815e33
Merge branch 'version-1.2.0-dev' into reauthenticate
Feb 17, 2017
5a920d0
Firebase Storage update
samtstern Feb 22, 2017
3b58af0
Merge remote-tracking branch 'firebase/version-2.0.0-dev' into reauth…
SUPERCILEX Feb 24, 2017
7223256
Cleanup
SUPERCILEX Feb 24, 2017
d764d3e
Fix broken tests
SUPERCILEX Feb 24, 2017
e3e4d41
Merge remote-tracking branch 'firebase/version-2.0.0-dev' into reauth…
SUPERCILEX Feb 24, 2017
888213e
Enhanced TaskFailureLogger Credentials with the specific credential t…
Feb 26, 2017
f2e3cc1
Merge pull request #612 from vieck/enhancement-taskfailurelogger
samtstern Feb 27, 2017
7810da2
Documentation update -- More details on running the sample app (#616)
hiranya911 Mar 1, 2017
b27def6
Update Android Gradle plugin to 2.3.0
friederbluemle Mar 3, 2017
2153c44
Merge pull request #620 from friederbluemle/update-gradle-plugin
samtstern Mar 3, 2017
18f4136
Update Gradle wrapper to 3.4.1
friederbluemle Mar 4, 2017
de40623
Merge pull request #622 from friederbluemle/update-gradle-wrapper
samtstern Mar 6, 2017
ac5c849
The Big Kahuna of firebase-ui-database (#544)
SUPERCILEX Mar 6, 2017
46704e9
Merge remote-tracking branch 'firebase/version-2.0.0-dev' into fix-re…
SUPERCILEX Mar 6, 2017
422db3a
Merge remote-tracking branch 'tmp/reauthenticate' into fix-reauth-pr
SUPERCILEX Mar 6, 2017
cf144b4
Update documentation and sample for #544 (#567)
SUPERCILEX Mar 6, 2017
e5c4d34
Merge "Firebase Storage update"
samtstern Mar 9, 2017
63df29c
Merge branch 'master' into version-2.0.0-dev
samtstern Mar 9, 2017
f158048
Merge remote-tracking branch 'firebase/version-2.0.0-dev' into fix-re…
SUPERCILEX Mar 13, 2017
0e16a9e
Merge branch 'reauthenticate' of https://github.com/amandle/FirebaseU…
SUPERCILEX Mar 13, 2017
9ae131a
Add reauthentication (#583)
amandle Mar 13, 2017
c830479
finish the KickOffActivity on dialog tap outside
Mar 13, 2017
1c5e87b
Merge pull request #629 from amandle/finish_on_cancel
samtstern Mar 13, 2017
ece96e5
Merge remote-tracking branch 'firebase/version-2.0.0-dev' into fix-re…
SUPERCILEX Mar 13, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,19 @@ For convenience, here are some examples:

There is a sample app in the `app/` directory that demonstrates most
of the features of FirebaseUI. Load the project in Android Studio and
run it on your Android device to see a demonstration.
run it on your Android device to see a demonstration.

Before you can run the sample app, you must create a project in
the Firebase console. Add an Android app to the project, and copy
the generated google-services.json file into the `app/` directory.
Also enable [anonymous authentication](https://firebase.google.com/docs/auth/android/anonymous-auth)
for the Firebase project, since some components of the sample app
requires it.

If you encounter a version incompatibility error between Android Studio
and Gradle while trying to run the sample app, try disabling the Instant
Run feature of Android Studio. Alternatively, update Android Studio and
Gradle to their latest versions.

## Contributing

Expand Down
3 changes: 3 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
<activity
android:name=".database.ChatActivity"
android:label="@string/name_chat"/>
<activity
android:name=".database.ChatIndexActivity"
android:label="@string/name_chat"/>

<!-- Auth UI demo -->
<activity
Expand Down
96 changes: 46 additions & 50 deletions app/src/main/java/com/firebase/uidemo/database/ChatActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,23 @@
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;

public class ChatActivity extends AppCompatActivity implements FirebaseAuth.AuthStateListener {
public class ChatActivity extends AppCompatActivity implements FirebaseAuth.AuthStateListener, View.OnClickListener {
private static final String TAG = "RecyclerViewDemo";

private FirebaseAuth mAuth;
private DatabaseReference mRef;
private DatabaseReference mChatRef;
protected DatabaseReference mChatRef;
private Button mSendButton;
private EditText mMessageEdit;
protected EditText mMessageEdit;

private RecyclerView mMessages;
private LinearLayoutManager mManager;
private FirebaseRecyclerAdapter<Chat, ChatHolder> mAdapter;
private TextView mEmptyListMessage;
protected FirebaseRecyclerAdapter<Chat, ChatHolder> mAdapter;
protected TextView mEmptyListMessage;

@Override
protected void onCreate(Bundle savedInstanceState) {
Expand All @@ -64,28 +62,9 @@ protected void onCreate(Bundle savedInstanceState) {
mMessageEdit = (EditText) findViewById(R.id.messageEdit);
mEmptyListMessage = (TextView) findViewById(R.id.emptyTextView);

mRef = FirebaseDatabase.getInstance().getReference();
mChatRef = mRef.child("chats");
mChatRef = FirebaseDatabase.getInstance().getReference().child("chats");

mSendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String uid = mAuth.getCurrentUser().getUid();
String name = "User " + uid.substring(0, 6);

Chat chat = new Chat(name, mMessageEdit.getText().toString(), uid);
mChatRef.push().setValue(chat, new DatabaseReference.CompletionListener() {
@Override
public void onComplete(DatabaseError error, DatabaseReference reference) {
if (error != null) {
Log.e(TAG, "Failed to write message", error.toException());
}
}
});

mMessageEdit.setText("");
}
});
mSendButton.setOnClickListener(this);

mManager = new LinearLayoutManager(this);
mManager.setReverseLayout(false);
Expand Down Expand Up @@ -126,33 +105,30 @@ public void onDestroy() {
}

@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
updateUI();
}
public void onClick(View v) {
String uid = mAuth.getCurrentUser().getUid();
String name = "User " + uid.substring(0, 6);

private void attachRecyclerViewAdapter() {
Query lastFifty = mChatRef.limitToLast(50);
mAdapter = new FirebaseRecyclerAdapter<Chat, ChatHolder>(
Chat.class, R.layout.message, ChatHolder.class, lastFifty) {
Chat chat = new Chat(name, mMessageEdit.getText().toString(), uid);
mChatRef.push().setValue(chat, new DatabaseReference.CompletionListener() {
@Override
public void populateViewHolder(ChatHolder holder, Chat chat, int position) {
holder.setName(chat.getName());
holder.setText(chat.getMessage());

FirebaseUser currentUser = mAuth.getCurrentUser();
if (currentUser != null && chat.getUid().equals(currentUser.getUid())) {
holder.setIsSender(true);
} else {
holder.setIsSender(false);
public void onComplete(DatabaseError error, DatabaseReference reference) {
if (error != null) {
Log.e(TAG, "Failed to write message", error.toException());
}
}
});

@Override
protected void onDataChanged() {
// If there are no chat messages, show a view that invites the user to add a message.
mEmptyListMessage.setVisibility(mAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
}
};
mMessageEdit.setText("");
}

@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
updateUI();
}

private void attachRecyclerViewAdapter() {
mAdapter = getAdapter();

// Scroll to bottom on new messages
mAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
Expand All @@ -165,6 +141,26 @@ public void onItemRangeInserted(int positionStart, int itemCount) {
mMessages.setAdapter(mAdapter);
}

protected FirebaseRecyclerAdapter<Chat, ChatHolder> getAdapter() {
Query lastFifty = mChatRef.limitToLast(50);
return new FirebaseRecyclerAdapter<Chat, ChatHolder>(
Chat.class,
R.layout.message,
ChatHolder.class,
lastFifty) {
@Override
public void populateViewHolder(ChatHolder holder, Chat chat, int position) {
holder.bind(chat);
}

@Override
public void onDataChanged() {
// If there are no chat messages, show a view that invites the user to add a message.
mEmptyListMessage.setVisibility(getItemCount() == 0 ? View.VISIBLE : View.GONE);
}
};
}

private void signInAnonymously() {
Toast.makeText(this, "Signing in...", Toast.LENGTH_SHORT).show();
mAuth.signInAnonymously()
Expand Down
28 changes: 19 additions & 9 deletions app/src/main/java/com/firebase/uidemo/database/ChatHolder.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import android.widget.TextView;

import com.firebase.uidemo.R;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;

public class ChatHolder extends RecyclerView.ViewHolder {
private final TextView mNameField;
Expand All @@ -36,7 +38,23 @@ public ChatHolder(View itemView) {
mGray300 = ContextCompat.getColor(itemView.getContext(), R.color.material_gray_300);
}

public void setIsSender(boolean isSender) {
public void bind(Chat chat) {
setName(chat.getName());
setText(chat.getMessage());

FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser();
setIsSender(currentUser != null && chat.getUid().equals(currentUser.getUid()));
}

private void setName(String name) {
mNameField.setText(name);
}

private void setText(String text) {
mTextField.setText(text);
}

private void setIsSender(boolean isSender) {
final int color;
if (isSender) {
color = mGreen300;
Expand All @@ -56,12 +74,4 @@ public void setIsSender(boolean isSender) {
((RotateDrawable) mRightArrow.getBackground()).getDrawable()
.setColorFilter(color, PorterDuff.Mode.SRC);
}

public void setName(String name) {
mNameField.setText(name);
}

public void setText(String text) {
mTextField.setText(text);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.firebase.uidemo.database;

import android.os.Bundle;
import android.view.View;

import com.firebase.ui.database.FirebaseIndexRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.uidemo.R;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;

public class ChatIndexActivity extends ChatActivity {
private DatabaseReference mChatIndicesRef;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mChatIndicesRef = FirebaseDatabase.getInstance().getReference().child("chatIndices");
}

@Override
public void onClick(View v) {
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
String name = "User " + uid.substring(0, 6);
Chat chat = new Chat(name, mMessageEdit.getText().toString(), uid);

DatabaseReference chatRef = mChatRef.push();
mChatIndicesRef.child(chatRef.getKey()).setValue(true);
chatRef.setValue(chat);

mMessageEdit.setText("");
}

@Override
protected FirebaseRecyclerAdapter<Chat, ChatHolder> getAdapter() {
return new FirebaseIndexRecyclerAdapter<Chat, ChatHolder>(
Chat.class,
R.layout.message,
ChatHolder.class,
mChatIndicesRef.limitToLast(50),
mChatRef) {
@Override
public void populateViewHolder(ChatHolder holder, Chat chat, int position) {
holder.bind(chat);
}

@Override
public void onChildChanged(EventType type,
DataSnapshot snapshot,
int index,
int oldIndex) {
super.onChildChanged(type, snapshot, index, oldIndex);

// TODO temporary fix for https://github.com/firebase/FirebaseUI-Android/issues/546
onDataChanged();
}

@Override
public void onDataChanged() {
// If there are no chat messages, show a view that invites the user to add a message.
mEmptyListMessage.setVisibility(getItemCount() == 0 ? View.VISIBLE : View.GONE);
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_image);
ButterKnife.bind(this);

// By default, Firebase Storage files require authentication to read or write.
// By default, Cloud Storage files require authentication to read or write.
// For this sample to function correctly, enable Anonymous Auth in the Firebase console:
// https://console.firebase.google.com/project/_/authentication/providers
FirebaseAuth.getInstance()
Expand Down Expand Up @@ -102,7 +102,7 @@ private void uploadPhoto(Uri uri) {
hideDownloadUI();
Toast.makeText(this, "Uploading...", Toast.LENGTH_SHORT).show();

// Upload to Firebase Storage
// Upload to Cloud Storage
String uuid = UUID.randomUUID().toString();
mImageRef = FirebaseStorage.getInstance().getReference(uuid);
mImageRef.putFile(uri)
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<string name="desc_chat">Demonstrates using a FirebaseRecyclerAdapter to load data from Firebase Database into a RecyclerView for a basic chat app.</string>
<string name="desc_auth_ui">Demonstrates the Firebase Auth UI flow, with customization options.</string>
<string name="desc_image">Demonstrates displaying an image from Firebase Storage using Glide.</string>
<string name="desc_image">Demonstrates displaying an image from Cloud Storage using Glide.</string>

<!-- strings for Auth UI demo activities -->
<eat-comment/>
Expand Down Expand Up @@ -47,7 +47,7 @@
<string name="configuration_required">Configuration is required - see README.md</string>
<string name="other_options_header">Other Options:</string>
<string name="enable_smartlock">Enable SmartLock for Passwords</string>
<string name="rational_image_perm">This sample will read an image from local storage to upload to Firebase Storage.</string>
<string name="rational_image_perm">This sample will read an image from local storage to upload to Cloud Storage.</string>
<string name="anonymous_auth_failed_msg">Anonymous authentication failed, various components of the demo will not work. Make sure your device is online and that Anonymous Auth is configured in your Firebase project(https://console.firebase.google.com/project/_/authentication/providers)</string>
<string name="extra_google_scopes">Example extra Google scopes</string>
<string name="games">Games</string>
Expand Down
Loading