Я кодировал социальное приложение, используя Kotlin. Недавно я добавил фрагмент поиска друзей в свое основное действие (основное действие состоит из трех фрагментов: домашняя страница, отклонение / принятие запроса на добавление в друзья и поиск друзей, которым вы можете отправлять запросы на добавление в друзья). Кроме того, у Main Activity есть макет вкладок, где это, прежде всего, фрагменты, и есть кнопка, которая направляет пользователей на страницу профиля. Вот где возникает проблема. Когда я пытаюсь выйти из системы, используя:
mAuth!!.signOut()
startActivity(Intent(applicationContext, LoginActivity::class.java))
finishAffinity()
, я получаю сообщение об ошибке:
Caused by: java.lang.IllegalAccessException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
at com.example.realtimechat.findfriends.FindFriendsFragment$onViewCreated$1.onCancelled(FindFriendsFragment.kt:104)
Но эта ошибка присутствует только тогда, когда я посещаю фрагмент FindFriends перед нажатием на профиль кнопку страницы, чтобы перенаправить приложение на страницу профиля, где я могу выйти. Например, если я запускаю приложение (которое начинается с домашнего фрагмента) и сразу набираю go на страницу профиля, чтобы выйти, ошибка исчезнет, и я успешно выйду из системы и перенаправлюсь на страницу входа. Однако, если я запускаю приложение, go для поиска фрагмента друзей, а затем go на страницу профиля для выхода из системы, я получаю сообщение об ошибке. Что-то я делаю не так?
(Кстати, у find friends есть вид ресайклера)
FindFriendsFragment.kt
package com.example.realtimechat.findfriends
import android.os.Bundle
import android.util.Log
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.*
import java.lang.NullPointerException
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) {
progressBar?.visibility = View.GONE
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) {
try {
progressBar?.visibility = View.GONE
Toast.makeText(activity, "Failed to fetch friend list ${error.message}", Toast.LENGTH_SHORT).show()
}catch (e: NullPointerException){
throw(IllegalAccessException(e.message))
}
}
})
}
}
FindFriendsAdapter.kt
package com.example.realtimechat.findfriends
import android.content.Context
import android.util.Log
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.bumptech.glide.load.engine.GlideException
import com.example.realtimechat.R
import com.example.realtimechat.common.Constants
import com.example.realtimechat.common.NodeNames
import com.example.realtimechat.requests.RequestsFragment
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!!.substring(friendModel.photoFileName!!.lastIndexOf("/")+1))
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)
}
}
Код ошибки направляет меня к этой части кода:
override fun onCancelled(error: DatabaseError) {
try {
progressBar?.visibility = View.GONE
Toast.makeText(activity, "Failed to fetch friend list ${error.message}", Toast.LENGTH_SHORT).show()
}catch (e: NullPointerException){
throw(IllegalAccessException(e.message))
}
}
В частности , это:
throw(IllegalAccessException(e.message))
Однако исходный код был:
override fun onCancelled(error: DatabaseError) {
progressBar?.visibility = View.GONE
Toast.makeText(activity, "Failed to fetch friend list ${error.message}", Toast.LENGTH_SHORT).show()
}
И ошибка направила меня на
Toast.makeText(activity, "Failed to fetch friend list ${error.message}", Toast.LENGTH_SHORT).show()
Мы будем очень благодарны за любую помощь / решение этой проблемы !!
ОБНОВЛЕНИЕ Я удалил тост из override fun onCancelled(error: DatabaseError)
и код работает нормально. Однако мне нужно, чтобы этот тост был очевиден, так что есть способ обойти это?