Skip to content

Update everything, remove deprecated stuff from updates, make Travis builds less flaky, and update storage sample #559

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jan 31, 2017
Merged
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ dependencies {
// The following dependencies are not required to use the Firebase UI library.
// They are used to make some aspects of the demo app implementation simpler for
// demonstrative purposes, and you may find them useful in your own apps; YMMV.
compile 'pub.devrel:easypermissions:0.2.1'
compile 'pub.devrel:easypermissions:0.3.0'
compile 'com.jakewharton:butterknife:8.5.1'
apt 'com.jakewharton:butterknife-compiler:8.5.1'
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5'
Expand Down
24 changes: 1 addition & 23 deletions app/src/main/java/com/firebase/uidemo/database/ChatActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

package com.firebase.uidemo.database;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
Expand All @@ -29,9 +28,8 @@

import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.uidemo.R;
import com.google.android.gms.tasks.OnCompleteListener;
import com.firebase.uidemo.util.SignInResultNotifier;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
Expand Down Expand Up @@ -188,24 +186,4 @@ private void updateUI() {
mSendButton.setEnabled(isSignedIn());
mMessageEdit.setEnabled(isSignedIn());
}

/**
* Notifies the user of sign in successes or failures beyond the lifecycle of an activity.
*/
private static class SignInResultNotifier implements OnCompleteListener<AuthResult> {
private Context mContext;

public SignInResultNotifier(Context context) {
mContext = context.getApplicationContext();
}

@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Toast.makeText(mContext, R.string.signed_in, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(mContext, R.string.sign_in_failed, Toast.LENGTH_SHORT).show();
}
}
}
}
71 changes: 39 additions & 32 deletions app/src/main/java/com/firebase/uidemo/storage/ImageActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,31 @@
import com.bumptech.glide.Glide;
import com.firebase.ui.storage.images.FirebaseImageLoader;
import com.firebase.uidemo.R;
import com.google.android.gms.tasks.OnCompleteListener;
import com.firebase.uidemo.util.SignInResultNotifier;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;

import java.util.Collections;
import java.util.List;
import java.util.UUID;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import pub.devrel.easypermissions.AfterPermissionGranted;
import pub.devrel.easypermissions.AppSettingsDialog;
import pub.devrel.easypermissions.EasyPermissions;

@SuppressWarnings("LogConditional")
public class ImageActivity extends AppCompatActivity {
public class ImageActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks {

private static final String TAG = "ImageDemo";
private static final int RC_CHOOSE_PHOTO = 101;
private static final int RC_IMAGE_PERMS = 102;
private static final String PERMS = Manifest.permission.READ_EXTERNAL_STORAGE;

private StorageReference mImageRef;

Expand All @@ -61,21 +62,9 @@ protected void onCreate(Bundle savedInstanceState) {
// By default, Firebase 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().signInAnonymously()
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
Log.d(TAG, "signInAnonymously:" + task.isSuccessful());
if (!task.isSuccessful()) {
Log.w(TAG, "signInAnonymously", task.getException());
Log.w(TAG, getString(R.string.anonymous_auth_failed_msg));

Toast.makeText(ImageActivity.this,
getString(R.string.anonymous_auth_failed_toast),
Toast.LENGTH_SHORT).show();
}
}
});
FirebaseAuth.getInstance()
.signInAnonymously()
.addOnCompleteListener(new SignInResultNotifier(this));
}

@Override
Expand All @@ -89,30 +78,26 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
} else {
Toast.makeText(this, "No image chosen", Toast.LENGTH_SHORT).show();
}
} else if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE
&& EasyPermissions.hasPermissions(this, PERMS)) {
choosePhoto();
}
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}

@OnClick(R.id.button_choose_photo)
@AfterPermissionGranted(RC_IMAGE_PERMS)
protected void choosePhoto() {
String perm = Manifest.permission.READ_EXTERNAL_STORAGE;
if (!EasyPermissions.hasPermissions(this, perm)) {
if (!EasyPermissions.hasPermissions(this, PERMS)) {
EasyPermissions.requestPermissions(this, getString(R.string.rational_image_perm),
RC_IMAGE_PERMS, perm);
RC_IMAGE_PERMS, PERMS);
return;
}

Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RC_CHOOSE_PHOTO);
}

protected void uploadPhoto(Uri uri) {
private void uploadPhoto(Uri uri) {
// Reset UI
hideDownloadUI();
Toast.makeText(this, "Uploading...", Toast.LENGTH_SHORT).show();
Expand All @@ -124,10 +109,11 @@ protected void uploadPhoto(Uri uri) {
.addOnSuccessListener(this, new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
//noinspection LogConditional
Log.d(TAG, "uploadPhoto:onSuccess:" +
taskSnapshot.getMetadata().getReference().getPath());
Toast.makeText(ImageActivity.this, "Image uploaded",
Toast.LENGTH_SHORT).show();
Toast.LENGTH_SHORT).show();

showDownloadUI();
}
Expand All @@ -137,7 +123,7 @@ public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
public void onFailure(@NonNull Exception e) {
Log.w(TAG, "uploadPhoto:onError", e);
Toast.makeText(ImageActivity.this, "Upload failed",
Toast.LENGTH_SHORT).show();
Toast.LENGTH_SHORT).show();
}
});
}
Expand Down Expand Up @@ -165,4 +151,25 @@ private void showDownloadUI() {

mImageView.setVisibility(View.VISIBLE);
}

@Override
public void onRequestPermissionsResult(int requestCode,
String[] permissions,
int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}

@Override
public void onPermissionsGranted(int requestCode, List<String> perms) {
// See #choosePhoto with @AfterPermissionGranted
}

@Override
public void onPermissionsDenied(int requestCode, List<String> perms) {
if (EasyPermissions.somePermissionPermanentlyDenied(this,
Collections.singletonList(PERMS))) {
new AppSettingsDialog.Builder(this).build().show();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.firebase.uidemo.util;

import android.content.Context;
import android.support.annotation.NonNull;
import android.widget.Toast;

import com.firebase.uidemo.R;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthResult;

/**
* Notifies the user of sign in successes or failures beyond the lifecycle of an activity.
*/
public class SignInResultNotifier implements OnCompleteListener<AuthResult> {
private Context mContext;

public SignInResultNotifier(Context context) {
mContext = context.getApplicationContext();
}

@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Toast.makeText(mContext, R.string.signed_in, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(mContext, R.string.anonymous_auth_failed_msg, Toast.LENGTH_LONG).show();
}
}
}
4 changes: 1 addition & 3 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@
<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="anonymous_auth_failed_toast">Authentication failed, uploads and downloads will not work.</string>
<string name="anonymous_auth_failed_msg">Anonymous authentication failed. 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="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>
<string name="extra_facebook_scopes">Example extra Facebook scopes</string>
Expand All @@ -69,5 +68,4 @@
<!-- strings for database demo activities -->
<string name="start_chatting">No messages. Start chatting at the bottom!</string>
<string name="signed_in">Signed In</string>
<string name="sign_in_failed">Sign In Failed</string>
</resources>
10 changes: 8 additions & 2 deletions auth/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,15 @@ android {

buildTypes {
release {
manifestPlaceholders = [enableFbLogging: true]

minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}

debug {
manifestPlaceholders = [enableFbLogging: false]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine, just add a comment here saying this is only for testing. Since in the real world library modules are always compiled in their 'release' variant. So our end users will see enableFbLogging=true always

}
}

testOptions {
Expand All @@ -36,7 +42,7 @@ dependencies {
compile "com.google.firebase:firebase-auth:$firebase_version"
compile "com.google.android.gms:play-services-auth:$firebase_version"

compile 'com.facebook.android:facebook-android-sdk:4.18.0'
compile 'com.facebook.android:facebook-android-sdk:4.19.0'
compile("com.twitter.sdk.android:twitter:2.3.0@aar") { transitive = true }

// The following libraries are needed to prevent incompatibilities with the facebook
Expand All @@ -45,7 +51,7 @@ dependencies {

testCompile 'junit:junit:4.12'
//noinspection NewerVersionAvailable, GradleDynamicVersion
testCompile 'org.mockito:mockito-core:2.5.+'
testCompile 'org.mockito:mockito-core:2.6.+'
testCompile 'org.robolectric:robolectric:3.2.2'
// See https://github.com/robolectric/robolectric/issues/1932#issuecomment-219796474
testCompile 'org.khronos:opengl-api:gl1.1-android-2.1_r1'
Expand Down
4 changes: 4 additions & 0 deletions auth/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
android:name="com.facebook.sdk.ApplicationId"
android:value="@string/facebook_application_id"/>

<meta-data
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SUPERCILEX Could we be inadvertently disabling something in developer's apps? What if they have a conflicting value in their AndroidManifest?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@samtstern cc4b64b is the best solution I can come up with. Since we are upgrading the Facebook sdk for people, they will expect the Facebook upgrade guide (remove the initializeApp) to work. With this latest commit, that will still work, but people will have to override our manifest if they want to disable it:

<meta-data
    android:name="com.facebook.sdk.AutoLogAppEventsEnabled"
    android:value="false"
    tools:replace="android:value"/>

android:name="com.facebook.sdk.AutoLogAppEventsEnabled"
android:value="${enableFbLogging}"/>

<activity
android:name=".KickoffActivity"
android:label=""
Expand Down
5 changes: 1 addition & 4 deletions auth/src/main/java/com/firebase/ui/auth/AuthUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import android.support.annotation.StyleRes;
import android.support.annotation.VisibleForTesting;

import com.facebook.FacebookSdk;
import com.facebook.login.LoginManager;
import com.firebase.ui.auth.ui.FlowParameters;
import com.firebase.ui.auth.ui.idp.AuthMethodPickerActivity;
Expand Down Expand Up @@ -347,9 +346,7 @@ public Void then(@NonNull Task<GoogleApiClient> task) throws Exception {
});

// Facebook sign out
if (FacebookSdk.isInitialized()) {
LoginManager.getInstance().logOut();
}
LoginManager.getInstance().logOut();

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did something change the Facebook SDK that we no longer need to deal with initialization?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@samtstern Since you noticed, I might as well explain it now instead of in my review. The easiest would be to read Facebook's release notes: https://developers.facebook.com/docs/android/change-log-4x#4_19_0 and the upgrade guide https://developers.facebook.com/docs/android/upgrading-4x#4180to4190.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SGTM

// Wait for all tasks to complete
return Tasks.whenAll(disableCredentialsTask, googleSignOutTask);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,14 @@ public FacebookProvider(Context context, AuthUI.IdpConfig idpConfig, @StyleRes i
} else {
mScopes = scopes;
}
FacebookSdk.sdkInitialize(appContext);
FacebookSdk.setWebDialogTheme(theme);
}

public static AuthCredential createAuthCredential(IdpResponse response) {
if (!response.getProviderType().equals(FacebookAuthProvider.PROVIDER_ID)) {
return null;
}
return FacebookAuthProvider
.getCredential(response.getIdpToken());
return FacebookAuthProvider.getCredential(response.getIdpToken());
}

@Override
Expand Down
Loading