I'm new to Android development and I have a direct question. I'm trying to save multiple images in Firebase storage in one task and get the respective DownlaodUrl. When I apply the code below, I get an error message.
java.lang.ClassCastException: com.google.firebase.storage.UploadTask$TaskSnapshot cannot be cast to com.google.firebase.storage.UploadTask
Follow implementation I use
import com.google.firebase.storage.UploadTask
val tasks = mutableListOf<UploadTask>()
var uploadTask = spaceRef.putBytes(data)
tasks.add(uploadTask)
Tasks.whenAllSuccess<UploadTask>(tasks).addOnSuccessListener { uploadTasks ->
val downloadUrls = mutableListOf<Uri>()
lifecycleScope.launch {
uploadTasks.forEach {
downloadUrls.add(it.await().storage.downloadUrl.await())
}
}
}
Related
com.google.mlkit.nl.translate.Translation.getClient
Image Screenshot
In Above Image i have Imported the getClient() but it agai it shows me to import
I just faced with this issue too, for a temporary time you can use Firebase Natural Language library. Document Here,
First in your grandle file insert this -
implementation 'com.google.firebase:firebase-ml-natural-language:22.0.0'
implementation 'com.google.firebase:firebase-ml-natural-language-translate-model:20.0.8'
For the translation model -
val options = FirebaseTranslatorOptions.Builder()
.setSourceLanguage(FirebaseTranslateLanguage.DE)
.setTargetLanguage(FirebaseTranslateLanguage.TR)
.build()
val englishGermanTranslator = FirebaseNaturalLanguage.getInstance().getTranslator(options)
englishGermanTranslator.downloadModelIfNeeded()
.addOnSuccessListener {
// Model downloaded successfully. Okay to start translating.
// (Set a flag, unhide the translation UI, etc.)
}
.addOnFailureListener { exception ->
// Model couldn’t be downloaded or other internal error.
// ...
}
englishGermanTranslator.translate(text)
.addOnSuccessListener { translatedText ->
Log.d("translate","done \t $translatedText")
}
.addOnFailureListener { exception ->
// Error.
// ...
}
I Hope it will be help to you
I have the following ArrayList of File.
var a = ArrayList<File>()
var b = ArrayList<File>()
var c = ArrayList<File>()
var d = ArrayList<File>()
var e = ArrayList<File>()
Once the application has started the above ArrayList will be filed with more than 144,000 files. The total size all these combined would nearly 3.5 GB. I want to sort them by lastModified() or length() within in a second and update the modified ArrayList into RecyclerView.
For ease of sorting I have made above ArrayList into a Array<ArrayList<File>> as follows :
val mList = arrayOf(a,b,c,d,e)
To speed up things I do everything in background thread. Code :
doAsync {
mList.forEach{ index ->
index.sortByDescending { it.lastModified() }
}
activityUiThread {
setRecyclerViewAdapter() // Update RecyclerView with new sorted files
}
}
Link to the library I used sort files do in background thread : https://github.com/Kotlin/anko
The above code takes nearly 3-5 seconds to execute. I want this to be done within a second. How to solve this issue ? I am doing this for android.
If needed Im ready to change the API to do the background task
I want this to be done within a second
Short: it is impossible in general case. File System (on Android or on any other OS) can be overloaded, so this operation can pause your application sometimes. Please note this.
However you can speedup the code by using the following algorithm:
Read file metadata in parallel
Sort files via these results.
Please use example below. Please note that it does a lot of parallel IO operations.
Benefits of this solution:
Metadatas are read from the separate context (which has thread limit, to avoid IO overuse)
Metadata of file X is read only one time.
Sorting algorithm works with operating memory only, e.g. it use ready data, which reduces IO access.
suspend fun sortFiles(files: Iterable<File>): List<File> {
val metadataReadTasks: List<Deferred<FileWithMetadata>> = withContext(Dispatchers.IO)
{
files.map { file ->
async {
FileWithMetadata(file)
}
}
}
val metadatas: List<FileWithMetadata> = metadataReadTasks.awaitAll()
return metadatas
.sorted()
.map {
it.file
}
}
private class FileWithMetadata(
val file: File
) : Comparable<FileWithMetadata> {
private val lastModified = file.lastModified()
private val length = file.length()
override fun compareTo(other: FileWithMetadata): Int {
return when (other.length) {
this.length -> other.lastModified.compareTo(this.lastModified)
else -> other.length.compareTo(this.length)
}
}
}
I am trying to upload multiple files to Firebase and would like to link it to another child when all the upload tasks are completed. To achieve this, I was trying to use coroutines in kotlin. Below is the code (Please correct me if I am wrong as I'm really bad in coroutines):
fun create(placemark: PlacemarkModel,callback: () -> Unit=fun(){})=runBlocking {
val key = db.child("users").child(userId).child("placemarks").push().key
placemark.id = key!!
placemarks.add(placemark)
db.child("users").child(userId).child("placemarks").child(key).setValue(placemark)
uploadImage(placemark.dp,"dp",placemark)
if (placemark.images.size>0){
placemark.images.forEach{
uploadImage(it,"images",placemark,placemark.images.indexOf(it))
}
}
And here is my uploadImage function which I intended to wait until it finishes running and pass back the URI to the main function
suspend fun uploadImage(image:String,
type:String,
placemark: PlacemarkModel,
index:Int=0,
callback:()->Unit=fun(){}):URI{
st = FirebaseStorage.getInstance().reference
info("Coroutines 2")
val imageRef = st?.child(userId + '/' + File(image).name)
val data=readAndCompress(image)
data?.let {
var uploadTask=imageRef?.putBytes(data)
uploadTask?.addOnFailureListener {
println(it.message)
}?.addOnSuccessListener { taskSnapshot ->
//I want to return the URI here however return is not allowed
}
}
}
Thank you for your time.
It turns out that I can add all the tasks in to list of Task and call
Tasks.whenAllSuccess(tasks).addCompleteListener{ //callback here }
I am exploring Firebase Storage and have created a new folder named "data" on my app's firebase console, with a file inside named "info.json".
Since it's a new project and I don't have authentication setup, I copied the public security rules and applied them for the app:
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write;
}
}
}
So far, I have only been using firebase-core for analytics, so I added firebase-storage. Firebase dependencies:
dependencies {
api 'com.google.firebase:firebase-storage:15.0.0'
api 'com.google.firebase:firebase-core:15.0.0'
}
Here's my code, copied from Firebase samples:
val storage = FirebaseStorage.getInstance()
val storageRef = storage.reference
val pathReference = storageRef.child("data/info.json")
val ONE_MEGABYTE = (1024 * 1024).toLong()
val task = pathReference.getBytes(ONE_MEGABYTE).addOnSuccessListener {
d { it.toString() }
}.addOnFailureListener {
it.printStackTrace()
d { it.toString() }
}
I am getting this error from last couple of hours:
E/StorageUtil: error getting token
java.util.concurrent.ExecutionException:
com.google.firebase.FirebaseApiNotAvailableException: firebase-auth is
not linked, please fall back to unauthenticated mode.
I have an App with Firestore. I have a lot of Repositories. They work from Firestore. When I call 2 method in same time then I got an error.
class CommentRepository : CommentRepositoryInterface {
val firebaseFirestore = FirebaseFirestore.getInstance()
companion object {
const val COLLECTION_NAME = "post_comments"
const val COMMENT_POST_ID_KEY = "postid"
}
override fun getPostCommentsById(postId: String): Observable<CommentModel> {
return Observable.create { subscriber ->
firebaseFirestore.collection(COLLECTION_NAME)
.whereEqualTo(COMMENT_POST_ID_KEY, postId)
.get()
.addOnCompleteListener { task ->
if (task.isSuccessful) {
for (document in task.result) {
if (document.exists()) {
val documentModel = document.toObject(CommentModel::class.java)
subscriber.onNext(documentModel)
}
}
subscriber.onComplete()
} else {
subscriber.onError(task.exception!!) // TODO
}
}
}
}
}
The another one is almost same like that, but that one is using another collection.
So when I called these functions, then I got the next error:
Internal error in Firestore (0.6.6-dev).
Caused by: java.lang.RuntimeException: Failed to gain exclusive lock to the Firestore client's offline persistence. This generally means you are using Firestore from multiple processes in your app. Keep in mind that multi-process Android apps execute the code in your Application class in all processes, so you may need to avoid initializing Firestore in your Application class. If you are intentionally using Firestore from multiple processes, you can only enable offline persistence (i.e. call setPersistenceEnabled(true)) in one of them.
In the MyApplication class I tried to set the Singleton's of firestore settings.
val settings = FirebaseFirestoreSettings.Builder()
.setPersistenceEnabled(true)
.build()
FirebaseFirestore.getInstance().firestoreSettings = settings
I found it in Firestore's Doc:
For Android and iOS, offline persistence is enabled by default.
Anyone have idea to solve this problem?
I've cleared the App's Caching and the problem solved.
Do it or just remove from the phone! :)