Здравствуйте, я разрабатываю приложение Kotlin и использую Firebase. Однако я столкнулся с этой ошибкой:
2020-08-05 00:56:45.764 9163-9296/com.example.realtimechat E/StorageException: StorageException has occurred.
Object does not exist at location.
Code: -13010 HttpResult: 404
2020-08-05 00:56:45.767 9163-9296/com.example.realtimechat E/StorageException: { "error": { "code": 404, "message": "Not Found. Could not get object", "status": "GET_OBJECT" }}
java.io.IOException: { "error": { "code": 404, "message": "Not Found. Could not get object", "status": "GET_OBJECT" }}
at com.google.firebase.storage.network.NetworkRequest.parseResponse(com.google.firebase:firebase-storage@@19.1.1:433)
at com.google.firebase.storage.network.NetworkRequest.parseErrorResponse(com.google.firebase:firebase-storage@@19.1.1:450)
at com.google.firebase.storage.network.NetworkRequest.processResponseStream(com.google.firebase:firebase-storage@@19.1.1:441)
at com.google.firebase.storage.network.NetworkRequest.performRequest(com.google.firebase:firebase-storage@@19.1.1:272)
at com.google.firebase.storage.network.NetworkRequest.performRequest(com.google.firebase:firebase-storage@@19.1.1:286)
at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(com.google.firebase:firebase-storage@@19.1.1:70)
at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(com.google.firebase:firebase-storage@@19.1.1:62)
at com.google.firebase.storage.GetDownloadUrlTask.run(com.google.firebase:firebase-storage@@19.1.1:76)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
Я пытаюсь получить информацию из Firebase, чтобы отобразить ее в представлении ресайклера, но я не знаю, что я делаю неправильно.
Мой фрагмент:
package com.example.realtimechat.findfriends
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.realtimechat.R
import com.example.realtimechat.common.Constants
import com.example.realtimechat.common.NodeNames
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.database.*
class FindFriendsFragment: Fragment() {
private var rvFindFriends: RecyclerView? = null
private var findFriendsAdapter: FindFriendAdapter? = null
private var findFriendsModelList: MutableList<FindFriendModel> = ArrayList()
private var tvEmptyFriendsList: TextView? = null
private var databaseReference: DatabaseReference? = null
private var currentUser: FirebaseUser? = null
private var progressBar: View? = null
private var databaseReferenceFriendRequests: DatabaseReference? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_find_friends, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
rvFindFriends = view.findViewById(R.id.rvFindFriends)
tvEmptyFriendsList = view.findViewById(R.id.tvEmptyFriendsList)
progressBar = view.findViewById(R.id.progressBar)
rvFindFriends!!.layoutManager = LinearLayoutManager(activity)
findFriendsModelList = ArrayList()
findFriendsAdapter = FindFriendAdapter(activity!!, findFriendsModelList)
rvFindFriends!!.adapter = findFriendsAdapter
databaseReference = FirebaseDatabase.getInstance().reference.child(NodeNames.USERS);
currentUser = FirebaseAuth.getInstance().currentUser;
databaseReferenceFriendRequests = FirebaseDatabase.getInstance().reference.child(NodeNames.FRIEND_REQUESTS).child(currentUser!!.uid);
tvEmptyFriendsList!!.visibility = View.VISIBLE;
progressBar!!.visibility = View.VISIBLE;
val query: Query = databaseReference!!.orderByChild(NodeNames.USERNAME)
query.addValueEventListener(object: ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
findFriendsModelList.clear()
for(ds: DataSnapshot in snapshot.children){
val userId = ds.key
if(userId.equals(currentUser?.uid)){
continue
}
if(ds.child(NodeNames.USERNAME).value !=null){
val username = ds.child(NodeNames.USERNAME).value.toString()
val photoFileName = ds.child(NodeNames.PHOTO).value.toString()
databaseReferenceFriendRequests!!.child(userId!!).addListenerForSingleValueEvent(object: ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
if(snapshot.exists()){
val requestType = snapshot.child(NodeNames.REQUEST_TYPE).value.toString()
if(requestType == Constants.REQUEST_STATUS_SENT){
findFriendsModelList.add(FindFriendModel(userId, photoFileName, username, true))
findFriendsAdapter!!.notifyDataSetChanged()
}
}else{
findFriendsModelList.add(FindFriendModel(userId, photoFileName, username, false))
findFriendsAdapter!!.notifyDataSetChanged()
}
}
override fun onCancelled(error: DatabaseError) {
progressBar?.visibility = View.GONE
}
})
progressBar?.visibility = View.GONE
tvEmptyFriendsList?.visibility = View.GONE
}
}
}
override fun onCancelled(error: DatabaseError) {
progressBar?.visibility = View.GONE
Toast.makeText(context, "Failed to fetch friend list ${error.message}", Toast.LENGTH_SHORT).show()
}
})
}
}
Мой адаптер:
package com.example.realtimechat.findfriends
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.realtimechat.R
import com.example.realtimechat.common.Constants
import com.example.realtimechat.common.NodeNames
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.database.DatabaseReference
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.storage.FirebaseStorage
class FindFriendAdapter(private val context: Context,
private val findFriendModelList: List<FindFriendModel> = mutableListOf()) : RecyclerView.Adapter<FindFriendAdapter.FindFriendViewHolder>() {
private var friendRequestDatabase: DatabaseReference? = null
private var currentUser: FirebaseUser? = null
private var userId: String? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FindFriendAdapter.FindFriendViewHolder {
val view: View = LayoutInflater.from(context).inflate(R.layout.custom_find_friends_layout, parent, false)
return FindFriendViewHolder(view)
}
override fun onBindViewHolder(holder: FindFriendAdapter.FindFriendViewHolder, position: Int) {
val friendModel = findFriendModelList[position]
holder.tvUsername.text = friendModel.username
val fileRef = FirebaseStorage.getInstance().reference.child(Constants.IMAGES_FOLDER + "/" + friendModel.photoFileName)
fileRef.downloadUrl.addOnSuccessListener { uri ->
Glide.with(context)
.load(uri)
.placeholder(R.drawable.ic_profileicon)
.error(R.drawable.ic_profileicon)
.into(holder.ivProfile)
}
friendRequestDatabase = FirebaseDatabase.getInstance().reference.child(NodeNames.FRIEND_REQUESTS)
currentUser = FirebaseAuth.getInstance().currentUser
if(friendModel.requestSent!!){
holder.btnSendRequest.visibility = View.GONE
holder.pbRequest.visibility = View.VISIBLE
}else{
holder.btnSendRequest.visibility = View.VISIBLE
holder.pbRequest.visibility = View.GONE
}
holder.btnSendRequest.setOnClickListener {
holder.btnSendRequest.visibility = View.GONE
holder.pbRequest.visibility = View.VISIBLE
userId = friendModel.userId
friendRequestDatabase!!.child(currentUser!!.uid).child(userId!!).child(NodeNames.REQUEST_TYPE)
.setValue(Constants.REQUEST_STATUS_SENT)
.addOnCompleteListener { task ->
if(task.isSuccessful){
friendRequestDatabase!!.child(userId!!).child(currentUser!!.uid).child(NodeNames.REQUEST_TYPE)
.setValue(Constants.REQUEST_STATUS_RECEIVED)
.addOnCompleteListener { task ->
if(task.isSuccessful){
Toast.makeText(context, "Request sent successfully!", Toast.LENGTH_SHORT).show()
holder.btnSendRequest.visibility = View.GONE
holder.pbRequest.visibility = View.GONE
holder.btnCancelRequest.visibility = View.VISIBLE
}
}.addOnFailureListener{ exception ->
Toast.makeText(context, "Failed to send request ${exception.localizedMessage}", Toast.LENGTH_SHORT).show()
holder.btnSendRequest.visibility = View.VISIBLE
holder.pbRequest.visibility = View.GONE
holder.btnCancelRequest.visibility = View.GONE
}
}
}.addOnFailureListener{ exception ->
Toast.makeText(context, "Failed to send request ${exception.localizedMessage}", Toast.LENGTH_SHORT).show()
holder.btnSendRequest.visibility = View.VISIBLE
holder.pbRequest.visibility = View.GONE
holder.btnCancelRequest.visibility = View.GONE
}
}
holder.btnCancelRequest.setOnClickListener {
holder.btnCancelRequest.visibility = View.GONE
holder.pbRequest.visibility = View.VISIBLE
userId = friendModel.userId
friendRequestDatabase!!.child(currentUser!!.uid).child(userId!!).child(NodeNames.REQUEST_TYPE)
.setValue(null)
.addOnCompleteListener { task ->
if(task.isSuccessful){
friendRequestDatabase!!.child(userId!!).child(currentUser!!.uid).child(NodeNames.REQUEST_TYPE)
.setValue(null)
.addOnCompleteListener { task ->
if(task.isSuccessful){
Toast.makeText(context, "Request cancelled successfully!", Toast.LENGTH_SHORT).show()
holder.btnSendRequest.visibility = View.VISIBLE
holder.pbRequest.visibility = View.GONE
holder.btnCancelRequest.visibility = View.GONE
}
}.addOnFailureListener{ exception ->
Toast.makeText(context, "Failed to cancel request ${exception.localizedMessage}", Toast.LENGTH_SHORT).show()
holder.btnSendRequest.visibility = View.GONE
holder.pbRequest.visibility = View.GONE
holder.btnCancelRequest.visibility = View.VISIBLE
}
}
}.addOnFailureListener{ exception ->
Toast.makeText(context, "Failed to cancel request ${exception.localizedMessage}", Toast.LENGTH_SHORT).show()
holder.btnSendRequest.visibility = View.GONE
holder.pbRequest.visibility = View.GONE
holder.btnCancelRequest.visibility = View.VISIBLE
}
}
}
override fun getItemCount(): Int {
return findFriendModelList.size
}
inner class FindFriendViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val ivProfile: ImageView = itemView.findViewById(R.id.ivProfilePic)
val tvUsername: TextView = itemView.findViewById(R.id.tvUsername)
val btnSendRequest: Button = itemView.findViewById(R.id.btnSendRequest)
val btnCancelRequest: Button = itemView.findViewById(R.id.btnCancelRequest)
val pbRequest: ProgressBar = itemView.findViewById(R.id.pbRequest)
}
}
Мой XML Файл для фрагмента:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".findfriends.FindFriendsFragment"
android:background="@android:color/white">
<include
android:id="@+id/progressBar"
layout="@layout/custom_progressbar"
android:visibility="gone"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvFindFriends"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</androidx.recyclerview.widget.RecyclerView>
<TextView
android:id="@+id/tvEmptyFriendsList"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:text="Friends list will appear here"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Любая помощь будет принята с благодарностью!