I have made a social media app where users can upload there pic. I want to add a delete option for the users in the app. I want the users to delete their pic from Firebase cloud storage whenever needed. Here is my code
val firebase_url = contentDTOs[p1].imageUrl
val storageRef =
firebase_url?.let { it1 ->
FirebaseFirestore.getInstance().collection("images").document(
it1
)
}
storageRef?.delete()?.addOnSuccessListener {
// File deleted successfully
Toast.makeText(context , "Deleted",Toast.LENGTH_SHORT).show()
}?.addOnFailureListener {
// Uh-oh, an error occurred!
Toast.makeText(context , "cannot delete",Toast.LENGTH_SHORT).show()
}
return#setOnLongClickListener true
But whenever I try to delete any image it returns me an error
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.videoapp, PID: 20522
java.lang.IllegalArgumentException: Invalid path (https://firebasestorage.googleapis.com/v0/b/video-app-af9bf.appspot.com/o/images%2FIMAGE_20201023_144632_.png?alt=media&token=9cd9d400-49ed-4f73-81b3-baa7668a8430). Paths must not contain // in them.
I think it's because you have
images%2FIMAGE_20201023_144632
fragment in your link. And %2F is encoded backslash. Unfortunately from your code is not clear, how this link is formed
Related
`
Hello I'm trying to load some images from Firebase Storage using downloadUrl but it always crashes and I don't know why I already set up rules in the storage but it still doesn't work
I added these dependencies
implementation 'com.google.firebase:firebase-storage-ktx'
implementation platform('com.google.firebase:firebase-bom:31.0.2')
My code is this:
`var storageRef = Firebase.storage.reference.child("post/$uId/$fileName.png") //I want to load image from a certain user
var imageUri:String?=null
storageRef.downloadUrl.addOnSuccessListener { Uri->
imageUri=Uri.toString()
}
-.addOnFailureListener {
Toast.makeText(this#UploadActivity, it.message, Toast.LENGTH_SHORT).show()
}`
Basically when debugging it doesn't enter addOnSuccessListener nor addOnfailureLister and imageUri remains null even though I can see that downloadUrl has translated the gs://... to https://firebase...
I also added these rules indise my firebase Storage
`rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
`
The reason is that it may take time to fetch the Image from Firebase storage and before you get the Image from firebase storage you try to load the Image in ImageView and the app crashes because the Uri is still null.
Try
Firebase.storage.reference.child("post/$uId/$fileName.png").
downloadUrl.addOnSuccessListener { Uri->
Glide.with(YOUR_ACTIVITY_CONTEXT).
load(Uri.toString()).
into(YOUR_IMAGE_VIEW)
}
-.addOnFailureListener {
Toast.makeText(this#UploadActivity, it.message, Toast.LENGTH_SHORT).show()
}`
For detailed knowledge of Glide Library here is the link
I follow this document to setup on-demand asset delivery like this:
// Get asset path
private fun getAbsoluteAssetPath(assetPack: String, relativeAssetPath: String): String? {
val assetPackPath: AssetPackLocation =
assetPackManager.getPackLocation(assetPack)
// asset pack is not ready
?: return null
val assetsFolderPath = assetPackPath.assetsPath()
return FilenameUtils.concat(assetsFolderPath, relativeAssetPath)
}
// download
assetPackManager.registerListener(downloadListener)
assetPackManager.fetch(listOf(packageName)).addOnCompleteListener{ res ->
Timber.i("Download $packageName ${res.isSuccessful}")
}
// access the file
var filePath = File(getAbsoluteAssetPath("myAssetPack", "test.png"));
// it throws java.io.FileNotFoundException when open this file.
There are a lot of crash reports from my users on Crashlytics, and look like it happens when they update the app with new asset package files on google play.
The problem is that I can't reproduce it on my devices.
Is there anyone know why this is happened?
P/s: before open the file, I already check the package existing and it is valid.
if(assetPackManager.getPackLocation(packageName) != null)
Can't insert a new conversation to Telephony.Sms.Conversations.CONTENT_URI.
Keep getting a Caused by: java.lang.NullPointerException: Uri must not be null exception.
Even though the uri has a value of "content://sms/conversations".
Situation - logic flow
I receive an SMS message from an unknown number.
I insert a conversation for the unknown number (if one not found).
I insert the message and associate it with the newly created conversation.
Dev setup
For learning purposes, I am creating an Android SMS application with Kotlin.
Android Emulator with Pixel XL API 26.
The application I'm working on is set as the default SMS app.
Can successfully send, receive and insert (code below) individual messages.
createMessage() - works
Below is the working code I wrote to insert a message when the phone receives an SMS.
fun createMessage(
resolver: ContentResolver,
threadId: Number,
body: String,
sentByUs: Boolean
): Message? {
val messageType = if (sentByUs) Telephony.Sms.MESSAGE_TYPE_SENT else Telephony.Sms.MESSAGE_TYPE_INBOX
val values = ContentValues()
values.put(Telephony.Sms.THREAD_ID, threadId.toInt())
values.put(Telephony.Sms.BODY, body)
values.put(Telephony.Sms.TYPE, messageType)
val result = resolver.insert(Telephony.Sms.CONTENT_URI, values)
return this.getMessage(resolver, result)
}
createConversation() - doesn't work
Below is the code I'm working on which tries to insert a new conversation.
fun createConversation(
resolver: ContentResolver,
senderPhoneNumber: String,
latestMessageText: String,
latestMessageTimestamp: Long,
latestMessageIsOurs: Boolean,
latestMessageWasRead: Boolean
): Conversation? {
val wasRead = if (latestMessageWasRead) 1 else 0
val isOurs = if (latestMessageIsOurs) Telephony.Sms.Conversations.MESSAGE_TYPE_SENT else Telephony.Sms.Conversations.MESSAGE_TYPE_INBOX
val values = ContentValues()
values.put(Telephony.Sms.Conversations.ADDRESS, senderPhoneNumber)
values.put(Telephony.Sms.Conversations.BODY, latestMessageText)
values.put(Telephony.Sms.Conversations.DATE, latestMessageTimestamp)
values.put(Telephony.Sms.Conversations.TYPE, isOurs)
values.put(Telephony.Sms.Conversations.READ, wasRead)
// -------------------------------------------------------------------------
// ------ Throws java.lang.NullPointerException: Uri must not be null ------
// -------------------------------------------------------------------------
val result = resolver.insert(Telephony.Sms.Conversations.CONTENT_URI, values)
return this.getConversation(resolver, result)
}
While executing the resolver.insert() the application crashes with the following error message:
Caused by: java.lang.NullPointerException: Uri must not be null
With the debugger attached I can see that the uri does have a value.
Telephony.Sms.Conversations.CONTENT_URI is "content://sms/conversations"
How does Google do it?
Found out that Google open sources its common Android apps.
Here's the code for the Messaging application:
https://android.googlesource.com/platform/packages/apps/Messaging/
While analyzing DatabaseHelper.java I came to the conclusion that they create a whole separate database from scratch.
And then work with that troughout the lifetime of the application.
Which confused me even more - why don't they use resolver.insert()?
I may be wrong, the program was overwhelming for a new guy like me.
Question
If Telephony.Sms.Conversations.CONTENT_URI has a value of "content://sms/conversations", why do I get the exception?
To investigate such issue you need to turn off logcat filtering for your app. Then you'll find an SQLiteException that will help find out what's actually wrong.
The NPE refers to the fact that the insert failed and return a null Uri instead of the appropriate Uri path of the new element.
Few days back, the code is working fine images getting displayed properly ,but when i tried to do testing after a week android studio started displaying error
java.lang.IllegalArgumentException: Path must not be empty.
at com.squareup.picasso.Picasso.load(Picasso.java:332)
at com.example.project.messeges.UserItem.bind(NewMessageActivity.kt:115)
at com.example.project.messeges.UserItem.bind(NewMessageActivity.kt:103)
I am using Groupie extension Kotlin, below is the code which used to work perfectly
class UserItem(val user: User): Item(){
override fun bind(viewHolder: GroupieViewHolder, position: Int) {
var userProfilePicLink: String? = null
var userProfilePic = viewHolder.itemView.findViewById<CircleImageView>(R.id.imageview_new_message)
userProfilePicLink = user.thumb_image
viewHolder.itemView.username_textview_new_message.text = user.username
Picasso.get().load(userProfilePicLink).into(userProfilePic)
Log.d(TAG, "Profilepic link: $userProfilePicLink")
}
override fun getLayout(): Int {
return R.layout.user_row_new_message
}
}
by remove Picasso i can get links in Logcat but when i enable i get above. What might caused the issue.
Logcat with adding Picasso
2020-01-21 17:50:13.439 6157-6157/com.example.project D/NewMessageActivity: Profilepic link: https://url
2020-01-21 17:50:13.452 6157-6157/com.example.project D/NewMessageActivity: Profilepic link: https://url
2020-01-21 17:50:13.461 6157-6157/com.example.project D/NewMessageActivity: Profilepic link: https://url
2020-01-21 17:50:13.471 6157-6157/com.luvpi.luvproject D/NewMessageActivity: Profilepic link: https://url
Your URL is invalid. The log tells you so:
Profilepic link: https://url
"https://url" is not a valid URL and is not going to load an image. Check your source data.
By just replacing parameters i can load pictures.
Picasso.get()
.load(user.thumb_image)
.into(viewHolder.itemView.imageview_new_message)
I am not sure why this works instead of defining val. Can any one please explain the difference between two of them and why this is one is working
I am using Cloudiary service in order to decrease the size of an uploaded video. I am getting back a URL of a picture (which I assume is the first frame of the video) back as a response. When trying to load the video from firebase I am for some reason getting a URL and not a URI. here is my method -
private void loadVideoUri(String storageUri) {
if (StringUtils.isBlank(storageUri)) {
return;
}
// load firebase storage
Task<Uri> downloadUrlTask = FirebaseStorage.getInstance().getReferenceFromUrl(storageUri).getDownloadUrl(); // -> crash happends here
if (getContext() instanceof Activity) {
downloadUrlTask.addOnCompleteListener((Activity) getContext(), mOnDownloadUrlCompleted);
} else {
downloadUrlTask.addOnCompleteListener(mOnDownloadUrlCompleted);
}
}
here is the full error -
java.lang.IllegalArgumentException: Firebase Storage URLs must point to an object in your Storage Bucket. Please obtain a URL using the Firebase Console or getDownloadUrl().
at com.google.firebase.storage.internal.Util.normalize(com.google.firebase:firebase-storage##16.0.5:134)
at com.google.firebase.storage.FirebaseStorage.getReferenceFromUrl(com.google.firebase:firebase-storage##16.0.5:281)
at com.onemdtalent.app.ui.views.mdview.FirebasePlayerView.loadVideoUri(FirebasePlayerView.java:156)