Reputation: 29
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>
Upvotes: 1
Views: 419
Reputation: 166
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()
...
}
Upvotes: 1
Reputation: 186
The problem here is that You are creating a Fragment instance in the LoginActivity, setting arguments for that Fragment, and then You start a new Activity MainActivity. You are not doing anything with this Fragment reference, it is basically forgotten after You change the Activity.
To better understand that, You should remind yourself of Object Oriented Programming basics + logic behind android Fragments + Activities.
I suggest to remove the Fragment creation in LoginActivity. Then what You can do to make it work is to:
Upvotes: 1