Skip to content

Commit fa82073

Browse files
authored
Merge pull request #15 from firebase/master
Pull latest changes
2 parents 81b7da9 + 0d126f4 commit fa82073

File tree

28 files changed

+560
-53
lines changed

28 files changed

+560
-53
lines changed

CONTRIBUTING.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,26 @@ need to be sure of various other things—for instance that you'll tell us if yo
1212
know that your code infringes on other people's patents. You don't have to sign
1313
the CLA until after you've submitted your code for review and a member has
1414
approved it, but you must do it before we can put your code into our codebase.
15+
16+
### Adding new features
17+
1518
Before you start working on a larger contribution, you should get in touch with
1619
us first through the issue tracker with your idea so that we can help out and
1720
possibly guide you. Coordinating up front makes it much easier to avoid
1821
frustration later on.
1922

23+
If this has been discussed in an issue, make sure to mention the issue number.
24+
If not, go file an issue about this to make sure this is a desirable change.
25+
26+
If this is a new feature please co-ordinate with someone on [FirebaseUI-iOS](https://github.com/firebase/FirebaseUI-iOS)
27+
to make sure that we can implement this on both platforms and maintain feature parity.
28+
Feature parity (where it makes sense) is a strict requirement for feature development in FirebaseUI.
29+
2030
### Code reviews
2131

2232
All submissions, including submissions by project members, require review. We
23-
use GitHub pull requests for this purpose.
33+
use Github pull requests for this purpose. We adhere to the
34+
[Google Java style guide](https://google.github.io/styleguide/javaguide.html).
2435

2536
### The small print
2637

README.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,16 @@ libraries.
2828
```groovy
2929
dependencies {
3030
// Single target that includes all FirebaseUI libraries
31-
compile 'com.firebaseui:firebase-ui:0.5.3'
31+
compile 'com.firebaseui:firebase-ui:0.6.0'
3232
3333
// FirebaseUI Database only
34-
compile 'com.firebaseui:firebase-ui-database:0.5.3'
34+
compile 'com.firebaseui:firebase-ui-database:0.6.0'
3535
3636
// FirebaseUI Auth only
37-
compile 'com.firebaseui:firebase-ui-auth:0.5.3'
37+
compile 'com.firebaseui:firebase-ui-auth:0.6.0'
38+
39+
// FirebaseUI Storage only
40+
compile 'com.firebaseui:firebase-ui-storage:0.6.0'
3841
}
3942
```
4043

@@ -50,6 +53,9 @@ firebase-ui-auth
5053
5154
firebase-ui-database
5255
|--- com.google.firebase:firebase-database
56+
57+
firebase-ui-storage
58+
|--- com.google.firebase:firebase-storage
5359
```
5460

5561
Each version of FirebaseUI has dependency on a fixed version of these libraries, defined as the variable `firebase_version`
@@ -61,6 +67,7 @@ For convenience, here are some examples:
6167

6268
| FirebaseUI Version | Firebase/Play Services Version |
6369
|--------------------|--------------------------------|
70+
| 0.6.0 | 9.6.0 |
6471
| 0.5.3 | 9.4.0 |
6572
| 0.4.4 | 9.4.0 |
6673
| 0.4.3 | 9.2.1 |
@@ -72,6 +79,7 @@ For convenience, here are some examples:
7279

7380
* [firebase-ui-database](database/README.md)
7481
* [firebase-ui-auth](auth/README.md)
82+
* [firebase-ui-storage](storage/README.md)
7583

7684
## Sample App
7785

app/build.gradle

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@ android {
1616

1717
buildTypes {
1818
release {
19-
minifyEnabled false
20-
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
19+
minifyEnabled true
20+
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
21+
22+
// For the purposes of the sample, allow testing of a proguarded release build
23+
// using the debug key
24+
signingConfig signingConfigs.debug
2125
}
2226
}
2327

@@ -32,16 +36,19 @@ dependencies {
3236

3337
compile project(path: ':auth')
3438
compile project(path: ':database')
39+
compile project(path: ':storage')
3540

3641
compile "com.google.firebase:firebase-database:${project.ext.firebase_version}"
3742
compile "com.google.firebase:firebase-auth:${project.ext.firebase_version}"
43+
compile "com.google.firebase:firebase-storage:${project.ext.firebase_version}"
3844
compile "com.google.android.gms:play-services-auth:${project.ext.firebase_version}"
3945

4046
// The following dependencies are not required to use the Firebase UI library.
4147
// They are used to make some aspects of the demo app implementation simpler for
4248
// demonstrative purposes, and you may find them useful in your own apps; YMMV.
4349
compile 'com.jakewharton:butterknife:8.0.1'
4450
compile 'com.github.bumptech.glide:glide:3.7.0'
51+
compile 'pub.devrel:easypermissions:0.2.0'
4552
apt 'com.jakewharton:butterknife-compiler:8.0.1'
4653
}
4754

app/proguard-rules.pro

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,11 @@
2020
# https://firebase-dot-devsite.googleplex.com/docs/auth/android/start/#proguard
2121
-keepattributes Signature
2222
-keepattributes *Annotation*
23+
24+
# See:
25+
# storage/README.md
26+
-assumenosideeffects class android.util.Log {
27+
public static *** w(...);
28+
public static *** d(...);
29+
public static *** v(...);
30+
}

app/src/main/AndroidManifest.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
package="com.firebase.uidemo">
44

55
<uses-permission android:name="android.permission.INTERNET" />
6+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
67

78
<application
89
android:allowBackup="true"
910
android:icon="@mipmap/ic_launcher"
1011
android:label="@string/app_name"
1112
android:theme="@style/AppTheme">
12-
1313
<activity android:name=".ChooserActivity">
1414
<intent-filter>
1515
<action android:name="android.intent.action.MAIN" />
@@ -27,10 +27,10 @@
2727
<activity
2828
android:name=".auth.AuthUiActivity"
2929
android:label="@string/name_auth_ui" />
30-
3130
<activity
3231
android:name=".auth.SignedInActivity"
3332
android:label="@string/name_auth_ui" />
33+
<activity android:name=".storage.ImageActivity"></activity>
3434
</application>
3535

3636
</manifest>

app/src/main/java/com/firebase/uidemo/ChooserActivity.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
import com.firebase.uidemo.auth.AuthUiActivity;
2929
import com.firebase.uidemo.database.ChatActivity;
30+
import com.firebase.uidemo.storage.ImageActivity;
3031

3132
import butterknife.BindView;
3233
import butterknife.ButterKnife;
@@ -37,16 +38,19 @@ public class ChooserActivity extends AppCompatActivity {
3738
private static final Class[] CLASSES = new Class[]{
3839
ChatActivity.class,
3940
AuthUiActivity.class,
41+
ImageActivity.class,
4042
};
4143

4244
private static final int[] DESCRIPTION_NAMES = new int[] {
4345
R.string.name_chat,
44-
R.string.name_auth_ui
46+
R.string.name_auth_ui,
47+
R.string.name_image
4548
};
4649

4750
private static final int[] DESCRIPTION_IDS = new int[] {
4851
R.string.desc_chat,
49-
R.string.desc_auth_ui
52+
R.string.desc_auth_ui,
53+
R.string.desc_image
5054
};
5155

5256
@BindView(R.id.list_view)
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
package com.firebase.uidemo.storage;
2+
3+
import android.Manifest;
4+
import android.content.Intent;
5+
import android.net.Uri;
6+
import android.os.Bundle;
7+
import android.provider.MediaStore;
8+
import android.support.annotation.NonNull;
9+
import android.support.v7.app.AppCompatActivity;
10+
import android.util.Log;
11+
import android.view.View;
12+
import android.widget.Button;
13+
import android.widget.ImageView;
14+
import android.widget.Toast;
15+
16+
import com.bumptech.glide.Glide;
17+
import com.firebase.ui.storage.images.FirebaseImageLoader;
18+
import com.firebase.uidemo.R;
19+
import com.google.android.gms.tasks.OnCompleteListener;
20+
import com.google.android.gms.tasks.OnFailureListener;
21+
import com.google.android.gms.tasks.OnSuccessListener;
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.storage.FirebaseStorage;
26+
import com.google.firebase.storage.StorageReference;
27+
import com.google.firebase.storage.UploadTask;
28+
29+
import java.util.UUID;
30+
31+
import butterknife.BindView;
32+
import butterknife.ButterKnife;
33+
import butterknife.OnClick;
34+
import pub.devrel.easypermissions.AfterPermissionGranted;
35+
import pub.devrel.easypermissions.EasyPermissions;
36+
37+
public class ImageActivity extends AppCompatActivity {
38+
39+
private static final String TAG = "ImageDemo";
40+
private static final int RC_CHOOSE_PHOTO = 101;
41+
private static final int RC_IMAGE_PERMS = 102;
42+
43+
private StorageReference mImageRef;
44+
45+
@BindView(R.id.button_choose_photo)
46+
Button mUploadButton;
47+
48+
@BindView(R.id.button_download_direct)
49+
Button mDownloadDirectButton;
50+
51+
@BindView(R.id.first_image)
52+
ImageView mImageView;
53+
54+
@Override
55+
protected void onCreate(Bundle savedInstanceState) {
56+
super.onCreate(savedInstanceState);
57+
setContentView(R.layout.activity_image);
58+
ButterKnife.bind(this);
59+
60+
// By default, Firebase Storage files require authentication to read or write.
61+
// For this sample to function correctly, enable Anonymous Auth in the Firebase console:
62+
// https://console.firebase.google.com/project/_/authentication/providers
63+
FirebaseAuth.getInstance().signInAnonymously()
64+
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
65+
@Override
66+
public void onComplete(@NonNull Task<AuthResult> task) {
67+
Log.d(TAG, "signInAnonymously:" + task.isSuccessful());
68+
if (!task.isSuccessful()) {
69+
Log.w(TAG, "signInAnonymously", task.getException());
70+
Log.w(TAG, getString(R.string.anonymous_auth_failed_msg));
71+
72+
Toast.makeText(ImageActivity.this,
73+
getString(R.string.anonymous_auth_failed_toast),
74+
Toast.LENGTH_SHORT).show();
75+
}
76+
}
77+
});
78+
}
79+
80+
@Override
81+
public void onActivityResult(int requestCode, int resultCode, Intent data) {
82+
super.onActivityResult(requestCode, resultCode, data);
83+
84+
if (requestCode == RC_CHOOSE_PHOTO) {
85+
if (resultCode == RESULT_OK) {
86+
Uri selectedImage = data.getData();
87+
uploadPhoto(selectedImage);
88+
} else {
89+
Toast.makeText(this, "No image chosen", Toast.LENGTH_SHORT).show();
90+
}
91+
}
92+
}
93+
94+
@Override
95+
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
96+
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
97+
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
98+
}
99+
100+
@OnClick(R.id.button_choose_photo)
101+
@AfterPermissionGranted(RC_IMAGE_PERMS)
102+
protected void choosePhoto() {
103+
String perm = Manifest.permission.READ_EXTERNAL_STORAGE;
104+
if (!EasyPermissions.hasPermissions(this, perm)) {
105+
EasyPermissions.requestPermissions(this, getString(R.string.rational_image_perm),
106+
RC_IMAGE_PERMS, perm);
107+
return;
108+
}
109+
110+
Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
111+
startActivityForResult(i, RC_CHOOSE_PHOTO);
112+
}
113+
114+
protected void uploadPhoto(Uri uri) {
115+
// Reset UI
116+
hideDownloadUI();
117+
Toast.makeText(this, "Uploading...", Toast.LENGTH_SHORT).show();
118+
119+
// Upload to Firebase Storage
120+
String uuid = UUID.randomUUID().toString();
121+
mImageRef = FirebaseStorage.getInstance().getReference(uuid);
122+
mImageRef.putFile(uri)
123+
.addOnSuccessListener(this, new OnSuccessListener<UploadTask.TaskSnapshot>() {
124+
@Override
125+
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
126+
Log.d(TAG, "uploadPhoto:onSuccess:" +
127+
taskSnapshot.getMetadata().getReference().getPath());
128+
Toast.makeText(ImageActivity.this, "Image uploaded",
129+
Toast.LENGTH_SHORT).show();
130+
131+
showDownloadUI();
132+
}
133+
})
134+
.addOnFailureListener(this, new OnFailureListener() {
135+
@Override
136+
public void onFailure(@NonNull Exception e) {
137+
Log.w(TAG, "uploadPhoto:onError", e);
138+
Toast.makeText(ImageActivity.this, "Upload failed",
139+
Toast.LENGTH_SHORT).show();
140+
}
141+
});
142+
}
143+
144+
@OnClick(R.id.button_download_direct)
145+
protected void downloadDirect() {
146+
// Download directly from StorageReference using Glide
147+
Glide.with(this)
148+
.using(new FirebaseImageLoader())
149+
.load(mImageRef)
150+
.centerCrop()
151+
.crossFade()
152+
.into(mImageView);
153+
}
154+
155+
private void hideDownloadUI() {
156+
mDownloadDirectButton.setEnabled(false);
157+
158+
mImageView.setImageResource(0);
159+
mImageView.setVisibility(View.INVISIBLE);
160+
}
161+
162+
private void showDownloadUI() {
163+
mDownloadDirectButton.setEnabled(true);
164+
165+
mImageView.setVisibility(View.VISIBLE);
166+
}
167+
}

0 commit comments

Comments
 (0)