This question already has an answer here:
Can't get download url from Firebase Storge in Android [duplicate]
(1 answer)
Closed 4 years ago.
i am trying to upload a file to firestore (with putBytes) and then its url to the database.
So i am doing the db update in the "onSuccessListener" of the storage task like this:
private void uploadFile(byte[] bookImg, final String bookName){
if(mUploadTask != null && mUploadTask.isInProgress()){
//... upload in progress ...
} else {
if (bookImg != null) {
StorageReference fileRef = mStorageRef.child(bookName);
mUploadTask = fileRef.putBytes(bookImg)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
StorageReference refToUploadedPic = taskSnapshot.getMetadata().getReference();
Uri uploadedPicUri = refToUploadedPic.getDownloadUrl().getResult();
Upload upload = new Upload(bookName,
uploadedPicUri.toString());
String uploadId = mDatabaseRef.push().getKey(); //creates new entry on db
mDatabaseRef.child(uploadId).setValue(upload); //saves the file metadata on the new entry
}
})
.addOnFailureListener(new OnFailureListener() {
//... handle Failure...
})
.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
//... handle onProgress...
});
} else {
Toast.makeText(this, "NoFile", Toast.LENGTH_LONG).show();
}
}
}
the picture is uploaded to the storage but when it gets to this line:
Uri uploadedPicUri = refToUploadedPic.getDownloadUrl().getResult();
i get this error:
java.lang.IllegalStateException: Task is not yet complete
at com.google.android.gms.common.internal.Preconditions.checkState(Unknown Source:8)
at com.google.android.gms.tasks.zzu.zzdq(Unknown Source:4)
at com.google.android.gms.tasks.zzu.getResult(Unknown Source:3)
at com.controllers.BookListActivity$4.onSuccess(BookListActivity.java:302)
at com.controllers.BookListActivity$4.onSuccess(BookListActivity.java:289)
at com.google.firebase.storage.zzi.zza(Unknown Source:13)
at com.google.firebase.storage.zzac.zza(Unknown Source:2)
at com.google.firebase.storage.zzaf.run(Unknown Source:6)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6665)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:781)
the thing is that when i am debugging and step into this line (with F7) everything works as expected....
any help??
think you need to add an OnSuccessListener<Uri> there:
refToUploadedPic.getDownloadUrl()
.addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
}
});
Related
suggest collectionusers collectionI have a simple suggestion page where I can type title and contents, then store some other information to the Firestore, show it on ListView pages. It works fine itself, but after I send it, an error pops and it shows the bug is the timestamp toDate on the listview pages
The order of activities is listview>sending page>listview.
//the send activity
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
v.getId();
String title = art1.getText().toString();
String content = art2.getText().toString();
Intent intent = new Intent(create_announce_main.this, SuggestionMain.class);
// DocumentReference documentReference = firebaseFirestore.collection("announce").document("ann");
Map<String, Object> suggest = new HashMap<>();
suggest.put("title", title);
suggest.put("content", content);
suggest.put("name", name);
suggest.put("recID", recID);
suggest.put("admin_name", "");
suggest.put("response_content", "");
suggest.put("response_status", "未回覆");
suggest.put("response_time",FieldValue.serverTimestamp());
suggest.put("createdAt", FieldValue.serverTimestamp());
firebaseFirestore.collection("Suggestion").document().set(suggest).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(create_announce_main.this, "added succesfully", Toast.LENGTH_LONG).show();
}
}
});
startActivity(intent);
}
});
to listview page
//the view
DocumentReference docRef = firebaseFirestore.collection("users").document(userID);
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
Log.d("TAG", "DocumentSnapshot data: " + document.getData());
recID = document.getString("recID");
firebaseFirestore.collection("Suggestion").whereEqualTo("recID",recID).orderBy("createdAt", Query.Direction.DESCENDING).addSnapshotListener((documentSnapshots, error) -> {
ar.clear();
for (DocumentSnapshot snapshot : documentSnapshots){
idlv = snapshot.getId();
Timestamp timestamp = (Timestamp) snapshot.getData().get("createdAt");
**Date date = timestamp.toDate();//the error is at here**
String date2 = date.toString();
ar.add(new itemAnnounce(R.drawable.notes, snapshot.getString("title"),"回饋於 "+date2,"回覆管理者:"+snapshot.getString("admin_name"),"回覆狀態:"+snapshot.getString("response_status"),idlv,url));
}
adapterAnnounce adapterAnnounce = new adapterAnnounce(getApplicationContext(), R.layout.list_row_announce, ar);
adapterAnnounce.notifyDataSetChanged();
lv1.setAdapter(adapterAnnounce);
lv1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Object selectedObj =adapterAnnounce.getItem(position).getId();// this will get you selected obj of itemAnnounce
String obj = (String)selectedObj.toString();
Intent i = new Intent(SuggestionMain.this, announce_Page.class);
i.putExtra("annId",obj);
startActivity(i);
}
});
});
} else {
Log.d("TAG", "No such document");
}
} else {
Log.d("TAG", "get failed with ", task.getException());
}
}
});
the error pops
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.districtapp, PID: 12764
java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.Date com.google.firebase.Timestamp.toDate()' on a null object reference
at com.example.districtapp.SuggestionMain$1.lambda$onComplete$0$SuggestionMain$1(SuggestionMain.java:65)
at com.example.districtapp.-$$Lambda$SuggestionMain$1$70rkZQjkWJS7wHwVoKS2O7TV5ls.onEvent(Unknown Source:4)
at com.google.firebase.firestore.Query.lambda$addSnapshotListenerInternal$2(Query.java:1133)
at com.google.firebase.firestore.Query$$Lambda$3.onEvent(Unknown Source:6)
at com.google.firebase.firestore.core.AsyncEventListener.lambda$onEvent$0(AsyncEventListener.java:42)
at com.google.firebase.firestore.core.AsyncEventListener$$Lambda$1.run(Unknown Source:6)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
I have impression about this sort of thing when I touch firestore the first time,So i tried to start the send activity first not the view,it works out but just for once,second time it shows the same bug,I tried to finish the whole activity listview when onclick to sendpage,still dont work,
Firestore is getting the data perfectly, and after restarting the app, listview shows the data, so the function is working though.
suggest field
You are getting NullPointerException because of the following line of code:
Date date = timestamp.toDate();
And this is because the timestamp object in:
Timestamp timestamp = (Timestamp) snapshot.getData().get("createdAt");
Has the value of null. To solve this, please change the above line of code to:
if (snapshot.getDate("createdAt") != null) {
Date timestamp = snapshot.getDate("createdAt");
//Do what you need to do with this timestamp
}
Besides that, a query like this:
firebaseFirestore.collection("Suggestion").whereEqualTo("recID",recID).orderBy("createdAt", Query.Direction.DESCENDING)
Requires an index. To add such an index please check my answer from the following post:
Firestore whereEqualTo, orderBy and limit(1) not working
I have the following code in my "AddFragment.java" file for adding data into firebase firestore, firebase storage and firebase database. Regarding firebase storage and firebase firestore working, the firebase database is not working, despite configured properly.
imageUpload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(filePath!=null) {
String LostPetName = petName.getText().toString().trim();
String userID = firebaseAuth.getCurrentUser().getUid();
String path = userID+"_"+filePath.hashCode()+".jpg";
StorageReference petPhotos = storageReference.child(path);
DocumentReference documentReference = firebaseFirestore.collection("Lost_Pets").document(path);
DatabaseReference myDatabase = firebaseDatabase.getReference("pets");
// -------------------------
// ADDING AN IMAGE START
petPhotos.putFile(filePath).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(getActivity(), "Imagine încărcată cu succes", Toast.LENGTH_SHORT).show();
// -------------------------
// ADDING A MAP LatLng START
String markerId = myDatabase.push().getKey();
AddMarker coord = new AddMarker(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude(), userID);
assert markerId != null;
myDatabase.child(markerId).setValue(coord);
// ADDING A MAP LatLng END
// -------------------------
petPhotos.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>()
{
#Override
public void onSuccess(Uri downloadUrl)
{
imgUri = downloadUrl.toString();
imgID = imgUri;
Map<String,Object> pet = new HashMap<>();
pet.put("LostPetName", LostPetName);
pet.put("img_id", imgID);
pet.put("markerLatitude", String.valueOf(lastKnownLocation.getLatitude()));
pet.put("markerLongitude", String.valueOf(lastKnownLocation.getLongitude()));
documentReference.set(pet);
}
});
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getActivity(), "Eșuare adăugare imagine", Toast.LENGTH_SHORT).show();
}
});
// ADDING AN IMAGE END
// -------------------------
}
else{
Toast.makeText(getActivity(),"Nu s-a ales o imagine pentru animalul pierdut", Toast.LENGTH_SHORT).show();
}
}
});
}
If I add a Log.d(TAG, String.valueOf(lastKnownLocation.getLatitude()) + String.valueOf(lastKnownLocation.getLongitude()) + userID) there after the setValue function I can see my data correctly in the log.
The AddMarker function is as follows.
public static class AddMarker {
public double lat;
public double lng;
public String senderUid;
public AddMarker(double lat, double lng, String senderUid) {
this.lat = lat;
this.lng = lng;
this.senderUid = senderUid;
}
}
I have my firebase configured correctly in my gradle file.
Account connected and implementation set:
implementation 'com.google.firebase:firebase-database:20.0.0'
and also the rules in Firebase:
{
"rules": {
".read": true,
".write": true
}
}
If somebody knows something I don't, please help me. I'd be grateful.
From the comment chain it sounds like you may have downloaded the google-services.json before the Realtime Database was created, which may lead to it using the wrong URL.
I recommend downloading an updated google-services.json, adding that to your Android app, and trying again. If that doesn't work, you can also specify the correct URL in the code with FirebaseDatabase.getInstance("rescue-a-soul-default-rtdb.europe-west1.firebasedatabase.app")....
Also see:
Firebase Database points to wrong database URL
I was wondering if there was a way to edit the name and email via code in Android Studio, to change it in Cloud Firestore. I made a program where it only changes the name in real-time and when logged off, and logged in again it changes back to the previous one which is in Cloud Firestore.
vardas is an EditText field in the app design.
My code:
public void updateProfile(final View view) {
view.setEnabled(false);
vardas1 = vardas.getText().toString();
FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
UserProfileChangeRequest request = new UserProfileChangeRequest.Builder()
.setDisplayName(vardas1)
.build();
firebaseUser.updateProfile(request)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
view.setEnabled(true);
Toast.makeText(Profile.this, "Sėkmingai atnaujintas profilis", Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
view.setEnabled(true);
Log.e(TAG, "onFailure: ", e.getCause());
}
});
}
I was wondering if there was a way to edit the name and email via code in Android Studio, to change it in Cloud Firestore.
Yes, there is. According to the official documentation regarding how to update a document in Cloud Firestore:
To update some fields of a document without overwriting the entire document, use the update() method.
Assuming you want to update the name and email of the authenticated user that exists at the following reference:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference usersRef = rootRef.collection("users");
DocumentReference uidRef = usersRef.document(uid);
Try the following lines of code:
uidRef.update(
"name", "John",
"email", "john#email.com"
).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "DocumentSnapshot successfully updated!");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "Error updating document", e);
}
});
The result of using this is code, is the update of the name property with "John".
What you are doing in your code is nothing else than updating the name in the FirebaseUser object. That operation is not related in any way with Firestore. So updating the FirebaseUser it doesn't mean that the user will be also updated in the Firestore database. There are two different separate operations that are not related.
This question already has an answer here:
Cannot Resolve method getDownloadUrl() [duplicate]
(1 answer)
Closed 3 years ago.
Plzz help me to solve te problem. This is the line:
String thumb_download_url=thumb_task.getResult().getDownloadUrl().toString();
And the code is as below:
StorageReference filepath=mStorageReference.child("profile_image").child(uid+".jpg");
final StorageReference thumb_file_path=mStorageReference.child("profile_image").child("thumbs").child(uid+".jpg");
//------STORING IMAGE IN FIREBASE STORAGE--------
filepath.putFile(resultUri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task) {
if(task.isSuccessful()){
#SuppressWarnings("VisibleForTests")
final String downloadUrl= task.getResult().getDownloadUrl().toString();
UploadTask uploadTask = thumb_file_path.putBytes(thumb_bytes);
//---------- STORING THUMB IMAGE INTO STORAGE REFERENCE --------
uploadTask.addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> thumb_task) {
#SuppressWarnings("VisibleForTests")
String thumb_download_url=thumb_task.getResult().getDownloadUrl().toString();
if(thumb_task.isSuccessful()){
Map update_HashMap=new HashMap();
update_HashMap.put("image",downloadUrl);
update_HashMap.put("thumb_image",thumb_download_url);
//--------ADDING URL INTO DATABASE REFERENCE--------
mDatabaseReference.updateChildren(update_HashMap).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
mProgressDialog.dismiss();
Toast.makeText(SettingActivity.this, "Uploaded Successfuly...", Toast.LENGTH_SHORT).show();
}
else{
mProgressDialog.dismiss();
Toast.makeText(getApplicationContext(), " Image is not uploading...", Toast.LENGTH_SHORT).show();
}
}
});
}
else{
mProgressDialog.dismiss();
Toast.makeText(getApplicationContext(), " Error in uploading Thumbnail..", Toast.LENGTH_SHORT).show();
}
}
});
You get the following error in Android Studio:
cannot find symbol method getDownloadUrl()
Because when you call getResult() method on the thumb_task object, the type of object that is returned is UploadTask.TaskSnapshot and as you can see there no getDownloadUrl() method in this class, hence the error. To get the download url in a correct way, please see my answer from the following post:
How to get the download url from Firebase Storage?
StorageReference newfilepath = mStorage.child("User Submission Images").child(user_id).child("photo1g.jpg");
newfilepath.putFile(photo1ImageUri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task) {
final Uri dwnldUri = task.getResult().getDownloadUrl();
businessDBRef.child(user_id).child("photos1").setValue(dwnldUri.toString());
StorageReference thumbpath = mStorage.child("User Submission Images").child(user_id);
thumbpath.child("thumb_photo1v.jpg").getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
businessDBRef.child(user_id).child("thumb1").setValue(uri.toString());
}
});
mProgess.dismiss();
Toast.makeText(getApplicationContext(), "Upload Successful", Toast.LENGTH_SHORT).show();
}
});
After the image gets uploaded i try to pass the download url of the thumbnail into the database but i assume that my code executes faster than the creation of the thumbnail so i get this
StorageException has occurred.
Object does not exist at location.
When checking the Firebase storage the thumbnail is there with the download url accessible. Is there any workaround for this? maybe a way to wait for the thumbnail to generate first and then get the download URl??