I am new to firebase... I am trying to get the fcm token when a user logs in my app and then store that token in realtime database in the "Users branch" like so
I watched many videos but only shows how to get it with only one activity and I have many. I followed the firebase documentation...but nothing worked out.
The point when I am trying to get the token is when there is a user created in firebase with email and password. I don't know if that is the right point to do it.
next I will show the code.
--->Model
@Parcelize data class PatientModel(
var image: String? = null,
var patientName: String? = null,
var phoneNumber: String? = null,
var email: String? = null,
var isDoctor:Boolean? = null,
var firebaseId: String? = null,
var patientAppToken: String? = null): Parcelable
--->signUp from RemoteDataSoruce (I am using mvvm). The line of code where I am trying to get the token is marked with "*"
fun signUp(
image: Uri,
name: String,
phoneNumber: String,
email: String,
password: String,
doctorLiscence: String? = null,
isDoctor: Boolean
): Flow<State<Any>> = flow<State<Any>> {
emit(State.loading(true))
val doctorModel: DoctorModel
val patientModel: PatientModel
val auth = Firebase.auth
val data = auth.createUserWithEmailAndPassword(email, password).await()
data.user?.let { currentUser ->
val appToken = createAppToken()*******
val path = uploadImage(currentUser.uid, image).toString()
if (isDoctor) {
doctorModel =
createDoctorModel(
path,
name,
phoneNumber,
email,
doctorLiscence,
isDoctor,
auth.uid!!,
appToken
)
createDoctor(doctorModel, auth)
} else {
patientModel =
createPatientModel(path, name, phoneNumber, email, isDoctor, auth.uid!!, appToken)
createPatient(patientModel, auth)
}
emit(State.succes("Email verification sent"))
}
}.catch {
emit(State.failed(it.message!!))
}.flowOn(Dispatchers.IO)
private fun createAppToken(): String {
var token = ""
FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
if (task.isSuccessful){
Log.w(TAG, "Fetching FCM registration token failed", task.exception)
return@addOnCompleteListener
}
token = task.result
Log.d("token", token.toString())
}
return token
}
---> FirebaseMessagingService
class FirebaseService:FirebaseMessagingService() {
companion object{
var sharedPref: SharedPreferences? = null
var token: String?
get() {
return sharedPref?.getString("token", "")
}
set(value) {
sharedPref?.edit()?.putString("token", value)?.apply()
}
}
override fun onNewToken(newToken: String) {
super.onNewToken(newToken)
token = newToken
}
----> Manifest
<service android:name=".utils.FirebaseService"
android:permission="com.google.android.c2dm.permission.SEND"
android:exported="false"
android:stopWithTask="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
The firebase docs says that "On initial startup of your app, the FCM SDK generates a registration token for the client app instance. If you want to target single devices or create device groups, you'll need to access this token by extending FirebaseMessagingService and overriding onNewToken." I am not sure if I am doing right because when i Log.d the token it says null and nothing is stored in firebase. I appreciate your time!
CodePudding user response:
There is a mistake in your code.
FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
if (task.isSuccessful){
Log.w(TAG, "Fetching FCM registration token failed", task.exception)
return@addOnCompleteListener
}
}
task.isSuccessful
block should store the token but it was return and loging error ?.
FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
if (!task.isSuccessful) {
Log.w(TAG, "Fetching FCM registration token failed", task.exception)
return@OnCompleteListener
}
// Get new FCM registration token
val token = task.result
// Log and toast
val msg = getString(R.string.msg_token_fmt, token)
Log.d(TAG, msg)
Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
})