Search code examples
androidfirebasekotlinandroid-fragmentsandroid-activity

How to pass data from Activity to Fragment KOTLIN?


I use a Login Screen with Firebase Auth and Firestore and linked Firestore and Firebase Auth with same e-mail. I am wanting when I login or register to app with e-mail, It have to pass to other Activity's Fragment if it will be successful I can access Firestore. I tried with Bundle and SafeArgs but it always give me null. I can't solve this annoying problem. I will leave my codes.

LoginActivity.kt

private val db = Firebase.firestore.collection("users")
private val auth = Firebase.auth
private lateinit var binding: ActivityLoginBinding

private fun loginUser(email: String, password: String) {
        if (email.isNotEmpty() && password.isNotEmpty()) {
            CoroutineScope(Dispatchers.IO).launch {
                try {
                    auth.signInWithEmailAndPassword(email, password)
                        .addOnSuccessListener {
                            val fragment = MainFragment()
                            val bundle = Bundle()
                            bundle.putString("mail", email)
                            fragment.arguments = bundle
                            checkLogged()
                            Toast.makeText(this@LoginActivity, "Welcome Again", Toast.LENGTH_SHORT)
                                .show()
                        }
                        .addOnFailureListener {
                            Toast.makeText(this@LoginActivity, it.message, Toast.LENGTH_LONG).show()
                        }.await()
                } catch (e: Exception) {
                    withContext(Dispatchers.Main) {
                        Toast.makeText(this@LoginActivity, e.message, Toast.LENGTH_LONG).show()
                    }
                }
            }
        }
    }

    private fun registerUser(email: String, password: String, user: User) {
        if (email.isNotEmpty() && password.isNotEmpty()) {
            CoroutineScope(Dispatchers.IO).launch {
                try {
                    auth.createUserWithEmailAndPassword(email, password)
                        .addOnSuccessListener {
                            db.document(user.email).set(user)
                            val fragment = MainFragment()
                            val bundle = Bundle()
                            bundle.putString("email", user.email)
                            fragment.arguments = bundle
                            checkLogged()
                            Toast.makeText(
                                this@LoginActivity,
                                "Welcome ${user.name}",
                                Toast.LENGTH_SHORT
                            ).show()
                        }.await()
                } catch (e: java.lang.Exception) {
                    withContext(Dispatchers.Main) {
                        Toast.makeText(this@LoginActivity, e.message, Toast.LENGTH_LONG).show()
                    }
                }
            }
        }
    }

    private fun checkLogged() {
        if (Firebase.auth.currentUser != null) {
            Firebase.auth.currentUser!!.reload()
            startActivity(Intent(this@LoginActivity, MainActivity::class.java))
            finish()
        } else {
            //
        }
    }

MainFragment.kt

class MainFragment : Fragment() {

private val db = Firebase.firestore.collection("users")
private lateinit var binding: FragmentMainBinding

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View {
    binding = FragmentMainBinding.inflate(inflater, container, false)
    if (arguments != null){
        val textName = arguments?.getString("email")
        binding.txtName.text = textName
    }
    return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

}

nav_graph.xml

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_graph"
    app:startDestination="@id/mainFragment">
    <fragment
        android:id="@+id/addMealFragment"
        android:name="com.meetozan.caloriecounter.AddMealFragment"
        android:label="fragment_add_meal"
        tools:layout="@layout/fragment_add_meal" />
    <fragment
        android:id="@+id/calendarFragment"
        android:name="com.meetozan.caloriecounter.CalendarFragment"
        android:label="fragment_calendar"
        tools:layout="@layout/fragment_calendar" />
    <fragment
        android:id="@+id/foodsFragment"
        android:name="com.meetozan.caloriecounter.FoodsFragment"
        android:label="fragment_foods"
        tools:layout="@layout/fragment_foods" />
    <fragment
        android:id="@+id/leaderboardFragment"
        android:name="com.meetozan.caloriecounter.LeaderboardFragment"
        android:label="fragment_leaderboard"
        tools:layout="@layout/fragment_leaderboard" />
    <fragment
        android:id="@+id/mainFragment"
        android:name="com.meetozan.caloriecounter.MainFragment"
        android:label="fragment_main"
        tools:layout="@layout/fragment_main">
        <action
            android:id="@+id/action_mainFragment_to_addMealFragment"
            app:destination="@id/addMealFragment" />
        <action
            android:id="@+id/action_mainFragment_to_calendarFragment"
            app:destination="@id/calendarFragment" />
        <action
            android:id="@+id/action_mainFragment_to_foodsFragment"
            app:destination="@id/foodsFragment" />
        <action
            android:id="@+id/action_mainFragment_to_leaderboardFragment"
            app:destination="@id/leaderboardFragment" />
        <argument
            android:name="email"
            app:argType="string"
            app:nullable="true" />
    </fragment>
    <activity
        android:id="@+id/loginActivity"
        android:name="com.meetozan.caloriecounter.LoginActivity"
        android:label="activity_login"
        tools:layout="@layout/activity_login" />
</navigation>

Solution

  • As mentioned by Mert Ozan, the Fragment reference created in LoginActivity.kt is not referenced in the Main Activity.

    Instead of trying to pass the Email Address from login activity to main activity. You can access the email of current signed in user directly at the Main Activity.

    Something like:

    private lateinit var auth: FirebaseAuth
    ...
    override fun onCreate(..)..{ // (or onCreateView depending where u want to access the email)
        ...
    
        auth = FirebaseAuth.getInstance()
        val email = auth.currentUser?.email.toString()
    
        ...
    }