Android Studio Firebase problem: nothing is displayed - firebase

I'm creating an app with 3 other people, I have my own branch on Github. I have a recycler view in layout folder and 3 files for my products: ProductListActivity, ProductModel and ProductAdapter. When I build, I have 0 error and I am connected to the correct firebase on Android Studio but absolutly nothing is displayed in my app, there is my code:
class ProductListActivity : AppCompatActivity() {
private lateinit var dbref : DatabaseReference
private lateinit var productRecyclerView: RecyclerView
private lateinit var productArrayList: ArrayList<ProductModel>
override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.fil_actu)
productRecyclerView = findViewById(R.id.market_list)
productRecyclerView.layoutManager = LinearLayoutManager(this)
productRecyclerView.setHasFixedSize(true)
productArrayList = arrayListOf<ProductModel>()
getProductData()
}
private fun getProductData() {
// connexion avec la base de données sur la table 'Products'
dbref = Firebase.database("https://tierchaser-default-rtdb.firebaseio.com/").getReference("Products")
dbref.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
if (snapshot.exists()) {
Toast.makeText(this#ProductListActivity, "snapshot exist", Toast.LENGTH_SHORT).show()
// boucle sur chaque produit qui sera contenu dans 'productSnapshot'
for (productSnapshot in snapshot.children) {
Toast.makeText(this#ProductListActivity, "bdd lu", Toast.LENGTH_SHORT).show()
// on récupère le produit actuel
val product = productSnapshot.getValue(ProductModel::class.java)
// on le met dans 'productArrayList'
productArrayList.add(product!!)
}
productRecyclerView.adapter = ProductAdapter(productArrayList)
} else {
Toast.makeText(this#ProductListActivity, "ERROR", Toast.LENGTH_SHORT).show()
}
}
override fun onCancelled(error: DatabaseError) {
Toast.makeText(this#ProductListActivity, error.message, Toast.LENGTH_SHORT).show()
}
})
}
}
class ProductAdapter(private val productList : ArrayList<ProductModel>) :
RecyclerView.Adapter<ProductAdapter.ProductViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProductViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.product_item,
parent, false)
return ProductViewHolder(itemView)
}
override fun onBindViewHolder(holder: ProductViewHolder, position: Int) {
val currentItem = productList[position]
holder.address.text = currentItem.address
holder.city.text = currentItem.city
holder.date.text = currentItem.date
//Glide.with(holder.itemView).load(currentItem.imageUrl).into(holder.itemView.findViewById(R.id.logoLocation))
}
override fun getItemCount(): Int {
return productList.size
}
class ProductViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView) {
val address : TextView = itemView.findViewById(R.id.address)
val city : TextView = itemView.findViewById(R.id.city)
val date : TextView = itemView.findViewById(R.id.date)
//val image : ImageView = itemView.findViewById(R.id.productImage)
}
}
data class ProductModel (var address : String ?= null, var city : String ?= null, var date : String ?= null)
I have all the required imports by the way, and the Toasts don't show up either
Thank you for help !

Related

Put pdf files which I download from Firebase Cloud Storage to recyclerview using Kotlin

I have prepared recyclerview to show pdf files but when I try some functions to put pdfs into recyclerview they didin't show. Is any function to do this?
This is my adapter and here probably all is well
class AdapterKarty(private val fileList: ArrayList<plik>): RecyclerView.Adapter<AdapterKarty.ViewHolder>(){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AdapterKarty.ViewHolder {
val a = LayoutInflater.from(parent.context).inflate(R.layout.karta_pliku,parent, false)
return ViewHolder(a);
}
override fun onBindViewHolder(holder: AdapterKarty.ViewHolder, position: Int) {
var item = fileList[position]
holder.dokument.text = item.Name
}
override fun getItemCount(): Int {
return fileList.size
}
inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
var dokument: TextView = itemView.tv_dokment
}
}
In list I use class plik where i declare only name because here i try put name of pdf
class plik( var Name: String?=null){
}
And here I have my main class where I try put those files to recyclerview
class Dokumenty : AppCompatActivity() {
private var stor: FirebaseStorage?=null
private var storageReference = stor?.reference
lateinit var recyclerView: RecyclerView
private lateinit var listaPlikow : ArrayList<plik>
private lateinit var myAdapter: AdapterKarty
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_dokumenty)
stor = FirebaseStorage.getInstance()
recyclerView = findViewById(R.id.recyclerView)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.setHasFixedSize(true)
listaPlikow = arrayListOf()
myAdapter = AdapterKarty(listaPlikow)
getFiles()
}
private fun getFiles() {
var pliki = storageReference?.child("Pliki/")
}
}

the date class from the real time database is not filled in

I can't fill in the date class from the database. I don't understand why it doesn't work, everything seems to be written correctly.
In the initUser function, the date of the User Model class is filled in, but if you write the USER variable to println, it will be empty. Below is the code of the MainActivity class, which has the initUser function
class MainActivity : AppCompatActivity() {
private lateinit var btn_settings: ImageButton
private lateinit var btn_add_friend: ImageButton
private lateinit var btn_search_main: ImageView
private lateinit var search_main: EditText
private lateinit var nickname_main: TextView
private lateinit var Id_main: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initFirebase()
initUser()
init()
initFunc()
btn_settings.setOnClickListener {
val intent = Intent(this, SettingsActivity::class.java)
startActivity(intent)
}
btn_search_main.setOnClickListener {
if (search_main.text.toString() == "Happy") {
val intent = Intent(this, psh::class.java)
startActivity(intent)
}
}
nickname_main.text = USER.username
Id_main.text = CURRENT_UID
println(USER)
}
private fun initFunc() {
if (AUTH.currentUser != null) {
} else {
val intent = Intent(this, LoginActivity::class.java)
startActivity(intent)
}
}
private fun init(){
btn_settings = findViewById(R.id.btn_settings)
btn_add_friend = findViewById(R.id.btn_add_friend)
btn_search_main = findViewById(R.id.btn_search_main)
search_main = findViewById(R.id.search_main)
nickname_main = findViewById(R.id.nickname_main)
Id_main = findViewById(R.id.Id_main)
}
private fun initUser(){
REF_DATABASE_ROOT.child(NODE_USERS).child(CURRENT_UID)
.addListenerForSingleValueEvent(AppValueEventListener{
USER = it.getValue(UserModel()::class.java) ?:UserModel()
})
}
fun initFirebase(){
AUTH = FirebaseAuth.getInstance()
REF_DATABASE_ROOT = FirebaseDatabase.getInstance("https://ert-d167-default-rtdb.europe-west1.firebasedatabase.app").reference
USER = UserModel()
CURRENT_UID = AUTH.currentUser?.uid.toString()
}
}
class AppValueEventListener (val onSuccess:(DataSnapshot)->Unit) : ValueEventListener{
override fun onCancelled(error: DatabaseError) {
}
override fun onDataChange(snapshot: DataSnapshot) {
onSuccess(snapshot)
}
}
data class UserModel(
var id: String = "",
var username: String = ""
)
If you insert the USER variable into print, it will be User Model(id=, username=)
The data in the database is

SetOnClickListener for Button within RecyclerView to access viewmodel and perform action on room database

I would like to add a "delete" button in a RecyclerView showing a list of "Users" present in a Room Database. The button should permit to delete the single user when clicking on the button. I have tried to insert a function in Myviewholder, but when I call it in OnBindViewHolder the error concerns the initialization of the mUserViewModel. Do you have any suggestion on it?
This is the adapter:
class ListAdapterUser: RecyclerView.Adapter<ListAdapterUser.MyViewHolder>() {
private var UserList = emptyList<User>()
private lateinit var mUserViewModel: UserViewModel
class MyViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
val button = itemView.findViewById<Button>(R.id.deleteoption)
fun deleteitem(item: User, viewModel: UserViewModel){
button.setOnClickListener{
viewModel.deleteUser(item)
}}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
return MyViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.custom_rowUser, parent, false))
}
override fun getItemCount(): Int {
return UserList.size
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val currentItem = UserList[position]
holder.itemView.textview_valueUser.text = currentItem.Uservalue.toString()
holder.deleteitem(currentItem, mUserViewModel)
}
fun setUserData(User: List<User>){
this.UserList = User
notifyDataSetChanged()
}
}
Thank you!
Solved obtaining the viewmodel initialized in the fragment passing it with setUserData function. Here the final code:
class ListAdapterUser: RecyclerView.Adapter<ListAdapterUser.MyViewHolder>() {
private var UserList = emptyList<User>()
private lateinit var mUserViewModel: UserViewModel
class MyViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
val button = itemView.findViewById<Button>(R.id.deleteoption)
fun deleteitem(item: User, viewModel: UserViewModel){
button.setOnClickListener{
viewModel.deleteUser(item)
}}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
return MyViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.custom_rowUser, parent, false))
}
override fun getItemCount(): Int {
return UserList.size
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val currentItem = UserList[position]
holder.itemView.textview_valueUser.text = currentItem.Uservalue.toString()
holder.deleteitem(currentItem, mUserViewModel)
}
fun setUserData(User: List<User>, viewModel: UserViewModel)){
this.UserList = User
this.mUserViewModel = viewModel
notifyDataSetChanged()
}}

Retrofit service works only once

I'm using retrofit to login to my API, but if, for example, I insert a wrong password and try to login again, the service is not called again.
It seems that the second call gets "stuck" in the repository, never reaches the service.
This is my first android app and i'm struggling with this situation.
Tks in advance for any help you can provide on this.
This is the code for my app.
DI
class Fiscalizacao : Application(), KodeinAware {
override val kodein = Kodein.lazy {
import(androidModule(this#Fiscalizacao))
bind() from singleton {
Autenticacao(
instance()
)
}
bind<IAutenticacaoDataSource>() with singleton {
AutenticacaoDataSourceImpl(
instance()
)
}
bind<IAuthenticationRepository>() with singleton {
AuthenticationRepositoryImpl(
instance()
)
}
bind() from provider { AutenticacaoViewModelFactory(instance(), instance()) }
}
override fun onCreate() {
super.onCreate()
AndroidThreeTen.init(this)
}
}
Service
interface Autenticacao {
#POST("auth")
fun authAsync(#Body user: RequestBody): Deferred<AutenticacaoResponseResource>
companion object {
operator fun invoke(connectivityInterceptor: IConnectivityInterceptor): Autenticacao {
val okHttpClient = OkHttpClient.Builder()
.build()
return Retrofit
.Builder()
.client(okHttpClient)
.baseUrl("http://10.110.100.216/identity/")
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(Autenticacao::class.java)
}
}
}
DataSource
class AutenticacaoDataSourceImpl(
private val autenticacao: Autenticacao
) :
IAutenticacaoDataSource {
private val _authResponse = MutableLiveData<AutenticacaoResponseResource>()
override val authResponse: LiveData<AutenticacaoResponseResource>
get() = _authResponse
override suspend fun auth(user: CredentialsResource?): LiveData<AutenticacaoResponseResource> {
try {
val userJsonObject = JsonObject()
userJsonObject.addProperty(Parameters.USERNAME.value, user?.utilizador)
userJsonObject.addProperty(Parameters.PASSWORD.value, user?.password)
val result = autenticacao
.authAsync(
userJsonObject.toString()
.toRequestBody(contentType = "application/json; charset=utf8".toMediaTypeOrNull())
)
.await()
_authResponse.postValue(result)
} catch (e: Exception) {
Log.e(e.cause.toString(), e.message, e)
}
return authResponse
}
}
Repository
class AuthenticationRepositoryImpl(
private val autenticacaoDataSource: IAutenticacaoDataSource
) : IAuthenticationRepository {
override suspend fun auth(user: CredentialsResource?): LiveData<AutenticacaoResponseResource> {
return withContext(Dispatchers.IO) {
return#withContext autenticacaoDataSource.auth(user)
}
}
}
ViewModel
class AutenticacaoViewModel(
private val authenticationRepository: IAuthenticationRepository,
) : ViewModel() {
lateinit var user:CredentialsResource
val login by lazyDeferred {
authenticationRepository.auth(user)
}
}
View Model Factory
class AutenticacaoViewModelFactory(private val authenticationRepository: IAuthenticationRepository, ) :
ViewModelProvider.NewInstanceFactory() {
#Suppress("UNCHECKED_CAST")
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return AutenticacaoViewModel(authenticationRepository) as T
}
}
Coroutines
fun <T> lazyDeferred(block: suspend CoroutineScope.() -> T): Lazy<Deferred<T>>{
return lazy {
GlobalScope.async(start = CoroutineStart.LAZY) {
block.invoke(this)
}
}
}
class AutenticacaoFragment : ScopedFragment(), KodeinAware {
override val kodein by closestKodein()
private val authViewModelFactory: AutenticacaoViewModelFactory by instance()
private lateinit var viewModel: AutenticacaoViewModel
val gson = Gson()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val binding: AutenticacaoFragmentBinding =
DataBindingUtil.inflate(inflater, R.layout.autenticacao_fragment, container, false)
binding.model =
AppGlobalObject
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProvider(this, authViewModelFactory)
.get(AutenticacaoViewModel::class.java)
mAutenticacao.setOnClickListener(listenerService)
}
private val listenerService =
View.OnClickListener {
when (it.id) {
R.id.mAutenticacao -> {
login(this.requireContext())
}
}
}
private fun login(context: Context) = launch {
viewModel.user = gson.fromJson(
gson.toJson(AppGlobalObject.autenticacao.user),
CredentialsResource::class.java
)
val result = viewModel.login.await()
result.observe(viewLifecycleOwner, Observer { response ->
if (response == null) return#Observer
val login = Utilities().validateStatusCodeOK(response.error)
when {
login -> {
Utilities().setLoginStatus(login, context)
}
else -> {
mPassword.error = "Erro no Login"
}
}
})
}

I am unable to use searchView with multiple fragments

In my application I have two fragments Fragment Card, Fragment Note. I am using ViewPager and TabLayout to sliding between two fragments. I want to implement a search function in my application.
This is my MainActivity class in Kotlin
class MainActivity : AppCompatActivity() {
private lateinit var viewPager:ViewPager
private lateinit var tabLayout:TabLayout
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
//toolbar.title = "Cards"
initComponent()
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_main, menu)
val sv: SearchView = menu!!.findItem(R.id.action_bar_search).actionView as SearchView
val sm = getSystemService(Context.SEARCH_SERVICE) as SearchManager
sv.setSearchableInfo(sm.getSearchableInfo(componentName))
sv.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(p0: String?): Boolean {
//loadQuery("%"+p0+"%")
return false
}
override fun onQueryTextChange(p0: String?): Boolean {
//loadQuery("%"+p0+"%")
return false
}
})
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
if (item != null) {
when (item.itemId) {
R.id.sort -> {
Toast.makeText(context, "sort note", Toast.LENGTH_SHORT).show()
}
R.id.settings -> {
Toast.makeText(context, "settings note", Toast.LENGTH_SHORT).show()
}
}
}
return super.onOptionsItemSelected(item)
}
private fun initComponent() {
viewPager = findViewById(R.id.view_pager)
setupViewPager(viewPager)
tabLayout = findViewById(R.id.tab_layout)
tabLayout.setupWithViewPager(viewPager)
viewPager.addOnPageChangeListener(object : ViewPager.SimpleOnPageChangeListener() {
override fun onPageSelected(position: Int) {
changeFabIcon(position)
toolbar.title = tabLayout.getTabAt(position)!!.text.toString()
super.onPageSelected(position)
}
})
fabT.setOnClickListener {
//var text = ""
when (viewPager.currentItem) {
0 -> {
// open add new card page
startActivity(Intent(this, AddCardActivity::class.java))
//text = "Add Card"
}
1 -> {
// open add new note page
startActivity(Intent(this, AddNoteActivity::class.java))
//text = "Add note"
}
}
//Toast.makeText(applicationContext, text, Toast.LENGTH_SHORT).show()
}
}
private fun changeFabIcon(index: Int) {
fabT.hide()
Handler().postDelayed({
when(index) {
0 -> {
fabT.setImageResource(R.drawable.ic_card)
}
1 -> {
fabT.setImageResource(R.drawable.ic_note)
}
}
fabT.show()
}, 400)
}
private fun setupViewPager(view_pager: ViewPager) {
val mAdapter = ViewPagerAdapter(supportFragmentManager)
mAdapter.addFragment(FragmentCard(), "Cards")
mAdapter.addFragment(FragmentNote(), "Notes")
view_pager.adapter = mAdapter
}
internal inner class ViewPagerAdapter(manager: FragmentManager) : FragmentPagerAdapter(manager) {
private val mFragmentList = ArrayList<Fragment>()
private val mFragmentTitleList = ArrayList<String>()
override fun getItem(position: Int): Fragment {
return mFragmentList[position]
}
override fun getCount(): Int {
return mFragmentList.size
}
fun addFragment(fragment: Fragment, title: String) {
mFragmentList.add(fragment)
mFragmentTitleList.add(title)
//fragment.arguments = args
}
override fun getPageTitle(position: Int): CharSequence? {
return mFragmentTitleList[position]
}
}
}
This is my FragmentNote class in Kotlin
class FragmentNote: Fragment() {
private var listNotes = ArrayList<Note> ()
private lateinit var mRecyclerViewNote: RecyclerView
private lateinit var mAdapterNote: RecyclerViewAdapterNote
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val v = inflater.inflate(R.layout.note_fragment, container, false)
mAdapterNote = RecyclerViewAdapterNote(context!!, listNotes, this)
mRecyclerViewNote = v.findViewById(R.id.noteRecView) as RecyclerView
mRecyclerViewNote.layoutManager = LinearLayoutManager(context)
mRecyclerViewNote.addItemDecoration(DividerItemDecoration(context, LinearLayoutManager.VERTICAL))
mRecyclerViewNote.adapter = mAdapterNote
setHasOptionsMenu(true)
NoteLoadQuery("%")
return v
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.menu_main, menu)
super.onCreateOptionsMenu(menu, inflater)
}
private fun NoteLoadQuery(title: String) {
var dbManager = DbManagerNote(context!!)
val projections = arrayOf("ID", "Title", "Description")
val selectionArgs = arrayOf(title)
// sort by title
val cursor = dbManager.Query(projections, "ID like ?", selectionArgs, "ID")
listNotes.clear()
// ascending
if (cursor.moveToLast()) {
do {
val ID = cursor.getInt(cursor.getColumnIndex("ID"))
val Title = cursor.getString(cursor.getColumnIndex("Title"))
val Description = cursor.getString(cursor.getColumnIndex("Description"))
listNotes.add(Note(ID, Title, Description))
} while (cursor.moveToPrevious())
}
mAdapterNote.notifyDataSetChanged()
}
}
and finally this is my FragmentCard class
class FragmentCard: Fragment() {
private var listCards = ArrayList<Card>()
private lateinit var myRecyclerViewCard: RecyclerView
private lateinit var mAdapter: RecyclerViewAdapterCard
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val v = inflater.inflate(R.layout.card_fragment, container, false)
mAdapter = RecyclerViewAdapterCard(context!!,listCards, this)
myRecyclerViewCard = v.findViewById(R.id.cardRecView) as RecyclerView
myRecyclerViewCard.layoutManager = LinearLayoutManager(context)
myRecyclerViewCard.addItemDecoration(DividerItemDecoration(context, LinearLayoutManager.VERTICAL))
myRecyclerViewCard.adapter = mAdapter
setHasOptionsMenu(true)
CardLoadQueryAscending("%")
return v
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.menu_main, menu)
super.onCreateOptionsMenu(menu, inflater)
}
private fun CardLoadQueryAscending(title: String) {
var dbManager = DbManagerCard(context!!)
val projections = arrayOf("ID", "CardName", "CardNum")
val selectionArgs = arrayOf(title)
// sort by title
val cursor = dbManager.Query(projections, "CardName like ?", selectionArgs, "CardName")
listCards.clear()
// ascending
if (cursor.moveToFirst()) {
do {
val ID = cursor.getInt(cursor.getColumnIndex("ID"))
val CardName = cursor.getString(cursor.getColumnIndex("CardName"))
val CardNum = cursor.getString(cursor.getColumnIndex("CardNum"))
listCards.add(Card(ID, CardName, CardNum))
} while (cursor.moveToNext())
}
mAdapter.notifyDataSetChanged()
}
}
I am trying to implement my search view in MainActivity, but I am unable to do. can anyone please give me your valuable suggestions to get my problem solve. thanks in advance.
I have done this, it is quite simple.
Just make your MainActivity own the SearchView. As you already did.
Then make a simple interface
ISearchChangedListener
onTextChanged(newString: String?)
onSearchSubmitted()
Setup your BaseFragment to implement this interface.
Override the implementation in your child fragments of the BaseFragment
Then keep track of mSelectedFragment on PageChanged.
Then you simply call
mSelectedFragment?.onTextChanged(newString)
whenever the parent gets a text changed and handle appropriately.

Resources