I can search firestore with mutable list of keywords via kotlin. But before of the search i can see all user details in recyclerview. But at the end when i search sucessfully a username then user comes the screen but i dont see user's details. In addition when i clcik on user it is possible see userdetails in userdetail acitivity without any problem. The main problem focused on after search procces. I need to fix it Thanks in advance))
Here is my result Here is my Firebase Firestore document
It is my data class
data class publiks(
val username: String = "",
val fullname: String = "",
var rating : Long = 0,
val rank: String = "",
val downloadUrl : String = "",
val userID : String = ""
) : Serializable
It is my some Activity codes
private lateinit var auth: FirebaseAuth
private lateinit var prUsers: RecyclerView
private var searchList: List<publiks> = ArrayList()
private var database: FirebaseFirestore = FirebaseFirestore.getInstance()
var posts_list = ArrayList<publiks>()
private var recyclerViewAdapter = new_adapter(posts_list, this)
private lateinit var swtest: EditText
////
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
get_information()
val searchText: String = swtest.text.toString()
searchData4(searchText.toLowerCase())
}
})
}
private fun searchData4(searchText: String) {
database.collection("ProfPic").whereArrayContains("lowercase_username", searchText).
get().addOnCompleteListener { task ->
if (task.isSuccessful) {
searchList = task.result!!.toObjects(publiks::class.java)
recyclerViewAdapter.post_list = searchList
recyclerViewAdapter.notifyDataSetChanged()
//////
private fun get_information() {
database.collection("ProfPic",).orderBy(
"Username",
Query.Direction.DESCENDING
).addSnapshotListener { snaphot, exception ->
if (exception != null) {
Toast.makeText(this, exception.localizedMessage, Toast.LENGTH_LONG).show()
} else {
if (snaphot != null) {
if (!snaphot.isEmpty) {
val documents = snaphot.documents
posts_list.clear()
for (document in documents) {
val usernamelady = document.get("Username") as String
val fullnamelady = document.get("Fullname") as String
val ranklady = document.get("Rank") as String
val ratinglady = document.get("Rating") as Long
val downloadUrl = document.get("downloadUs") as String
var userID = document.get("userID") as String
val download_post = publiks( usernamelady, fullnamelady, ratinglady, ranklady, downloadUrl, userID
)
posts_list.add(download_post)
}
}
recyclerViewAdapter.notifyDataSetChanged()
Related
1) This is the create campaign activity which creates the campaign and candidate
class CreateCampaignActivity : AppCompatActivity() {
private lateinit var startDateTimeTextView: TextView
private lateinit var endDateTimeTextView: TextView
private lateinit var titleEditText: TextInputEditText
private lateinit var db: FirebaseFirestore
private lateinit var candidate1Text: TextInputEditText
private lateinit var candidate2Text: TextInputEditText
private lateinit var candidate3Text: TextInputEditText
private lateinit var addCampaignButton : Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_create_campaign)
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
supportActionBar!!.title = "Create New Campaign"
titleEditText = findViewById(R.id.textTitle)
startDateTimeTextView = findViewById(R.id.start_date_time)
endDateTimeTextView = findViewById(R.id.end_date_time)
addCampaignButton = findViewById(R.id.btnAddCampaign)
candidate1Text = findViewById(R.id.textCandidate1)
candidate2Text = findViewById(R.id.textCandidate2)
candidate3Text = findViewById(R.id.textCandidate3)
db = FirebaseFirestore.getInstance()
addCampaignButton.setOnClickListener {
val title = titleEditText.text.toString().trim()
val startDateTime = startDateTimeTextView.text.toString().trim()
val endDateTime = endDateTimeTextView.text.toString().trim()
val candidate1Name = candidate1Text.text.toString().trim()
val candidate2Name = candidate2Text.text.toString().trim()
val candidate3Name = candidate3Text.text.toString().trim()
if (title.isEmpty() || startDateTime.isEmpty() || endDateTime.isEmpty() || candidate1Name.isEmpty() || candidate2Name.isEmpty() || candidate3Name.isEmpty()) {
Toast.makeText(this#CreateCampaignActivity, "Please fill up empty fields", Toast.LENGTH_SHORT).show()
} else if (!isEndTimeValid(startDateTime, endDateTime)) {
// Show error message or toast indicating that end time must be after start time
Toast.makeText(this#CreateCampaignActivity, "The end time must be after start time", Toast.LENGTH_SHORT).show()
} else {
val format = SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US)
val startTimestamp = Timestamp(format.parse(startDateTime)!!)
val endTimestamp = Timestamp(format.parse(endDateTime)!!)
val campaign = Campaign(
id = UUID.randomUUID().toString(),
title = title,
startDateTime = startTimestamp,
endDateTime = endTimestamp,
candidate1 = Candidate(
id = UUID.randomUUID().toString(),
name = candidate1Name
),
candidate2 = Candidate(
id = UUID.randomUUID().toString(),
name = candidate2Name
),
candidate3 = Candidate(id = UUID.randomUUID().toString(), name = candidate3Name)
)
// Add the campaign to the Firestore database
db.collection("campaigns")
.add(campaign)
.addOnSuccessListener { documentReference ->
campaign.id = documentReference.id
Log.d(
TAG,
"Campaign successfully added to Firestore with ID: ${documentReference.id}"
)
// Show success message or toast indicating that the campaign was successfully added
Toast.makeText(this#CreateCampaignActivity, "Campaign successfully added", Toast.LENGTH_SHORT).show()
// Clear the input fields
titleEditText.setText("")
startDateTimeTextView.text = ""
endDateTimeTextView.text = ""
candidate1Text.setText("")
candidate2Text.setText("")
candidate3Text.setText("")
// Navigate back to the previous activity
finish()
}
.addOnFailureListener { e ->
Log.w(TAG, "Error adding campaign to Firestore", e)
// Show error message or toast indicating that there was an error adding the campaign
Toast.makeText(this#CreateCampaignActivity, "Error adding campaign", Toast.LENGTH_SHORT).show()
}
}
startDateTimeTextView.setOnClickListener {
showStartDateTimeDialog()
}
endDateTimeTextView.setOnClickListener {
showEndDateTimeDialog()
}
}
}
private fun showStartDateTimeDialog() {
// Code to show the DatePicker and TimePicker dialogs
val calendar = Calendar.getInstance()
val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, month, day ->
calendar.set(Calendar.YEAR, year)
calendar.set(Calendar.MONTH, month)
calendar.set(Calendar.DAY_OF_MONTH, day)
val timeSetListener = TimePickerDialog.OnTimeSetListener { _, hour, minute ->
calendar.set(Calendar.HOUR_OF_DAY, hour)
calendar.set(Calendar.MINUTE, minute)
startDateTimeTextView.text =
SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault()).format(calendar.time)
}
TimePickerDialog(
this#CreateCampaignActivity,
timeSetListener,
calendar.get(Calendar.HOUR_OF_DAY),
calendar.get(Calendar.MINUTE),
true
).show()
}
DatePickerDialog(
this#CreateCampaignActivity,
dateSetListener,
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH)
).show()
}
private fun showEndDateTimeDialog() {
// Code to show the DatePicker and TimePicker dialogs
val calendar = Calendar.getInstance()
val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, month, day ->
calendar.set(Calendar.YEAR, year)
calendar.set(Calendar.MONTH, month)
calendar.set(Calendar.DAY_OF_MONTH, day)
val timeSetListener = TimePickerDialog.OnTimeSetListener { _, hour, minute ->
calendar.set(Calendar.HOUR_OF_DAY, hour)
calendar.set(Calendar.MINUTE, minute)
endDateTimeTextView.text =
SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault()).format(calendar.time)
}
TimePickerDialog(
this#CreateCampaignActivity,
timeSetListener,
calendar.get(Calendar.HOUR_OF_DAY),calendar.get(Calendar.MINUTE),
true
).show()
}
DatePickerDialog(
this#CreateCampaignActivity,
dateSetListener,
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH)
).show()
}
private fun isEndTimeValid(startDateTime: String, endDateTime: String): Boolean {
// Code to check if the end time is valid (i.e. after the start time)
val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault())
val startDate = sdf.parse(startDateTime)
val endDate = sdf.parse(endDateTime)
return endDate?.after(startDate) ?: false
}
companion object {
private const val TAG = "CreateCampaignActivity"
}
}
2) This is the edit campaign Activity to edit and delete campaign
class EditCampaignActivity : AppCompatActivity() {
private lateinit var datetimeTextView: TextView
private lateinit var titleEditText: TextInputEditText
private lateinit var db: FirebaseFirestore
private lateinit var candidate1Text: TextInputEditText
private lateinit var candidate2Text: TextInputEditText
private lateinit var candidate3Text: TextInputEditText
private lateinit var editCampaign : Button
private lateinit var delCampaign: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_edit_campaign)
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
supportActionBar!!.title = "Edit Campaign"
titleEditText = findViewById(R.id.textTitle)
datetimeTextView = findViewById(R.id.DateTime)
delCampaign = findViewById(R.id.btndelCampaign)
editCampaign = findViewById(R.id.btnSaveCampaign)
db = FirebaseFirestore.getInstance()
candidate1Text = findViewById(R.id.textCandidate1)
candidate2Text = findViewById(R.id.textCandidate2)
candidate3Text = findViewById(R.id.textCandidate3)
intent.getStringExtra("CAMPAIGN_ID")
val campaign = intent.getParcelableExtra<Campaign>("CAMPAIGN_DATA")
if (campaign != null) {
intent.putExtra("CAMPAIGN_ID", campaign.id)
}
if (campaign != null) {
titleEditText.setText(campaign.title)
}
if (campaign != null) {
datetimeTextView.text = campaign.endDateTime.toDate().toString()
}
if (campaign != null) {
candidate1Text.setText(campaign.candidate1.name)
}
if (campaign != null) {
candidate2Text.setText(campaign.candidate2.name)
}
if (campaign != null) {
candidate3Text.setText(campaign.candidate3.name)
}
//Update function
editCampaign.setOnClickListener {
// Update the fields of the Campaign object
val updatedTitle = titleEditText.text.toString()
val updatedCandidate1 = candidate1Text.text.toString()
val updatedCandidate2 = candidate2Text.text.toString()
val updatedCandidate3 = candidate3Text.text.toString()
campaign?.apply {
title = updatedTitle
endDateTime = Timestamp.now()
candidate1.name = updatedCandidate1
candidate2.name = updatedCandidate2
candidate3.name = updatedCandidate3
}
if (campaign != null) {
db.collection("campaigns").document(campaign.id)
.update(mapOf(
"title" to updatedTitle,
"endDateTime" to Timestamp.now(),
"candidate1" to mapOf(
"name" to updatedCandidate1
),
"candidate2" to mapOf(
"name" to updatedCandidate2
),
"candidate3" to mapOf(
"name" to updatedCandidate3
)
))
.addOnSuccessListener {
// Update successful, show a message to the user
Toast.makeText(this, "Campaign updated", Toast.LENGTH_SHORT).show()
}
.addOnFailureListener {
// Update failed, show an error message
Toast.makeText(this, "Error updating campaign: $it", Toast.LENGTH_SHORT).show()
}
}
// Confirm the edit action with the user
AlertDialog.Builder(this)
.setTitle("Edit Campaign")
.setMessage("Are you sure you want to save the changes to this campaign?")
.setPositiveButton("Yes") { _, _ ->
// Navigate back to the OrganiserActivity
finish()
}
.setNegativeButton("No", null)
.show()
}
// perform delete function
delCampaign.setOnClickListener {
// Show a message dialog to confirm the delete action
AlertDialog.Builder(this)
.setTitle("Delete Campaign")
.setMessage("Are you sure you want to delete this campaign?")
.setPositiveButton("Yes") { _, _ ->
if (campaign != null) {
deleteCampaign(campaign)
}
}
.setNegativeButton("No", null)
.show()
}
}
private fun deleteCampaign(campaign: Campaign) {
db.collection("campaigns").document(campaign.id).delete()
.addOnSuccessListener {
// Navigate back to the OrganiserActivity
finish()
}
.addOnFailureListener { e ->
// Show an error message
Toast.makeText(this, "Error deleting campaign: ${e.message}", Toast.LENGTH_SHORT).show()
}
}
}
The problem is I can't perform the delete and update function in the edit campaign activity. Whenever I created a new campaign from createCampaignActivity, I tried to edit the campaign and it states in the message dialog that firestore database has no document to update even though the document exists in the firestorm. How to solve this issue?
I am trying to get the user uid after creating an account, so I can create a document on Firestore with the uid as document id. The problem is that I get only null, everything is working fine and I'm able to sign the user and receive the code but the uid is always null.
I know I'm accessing the uid before it's initialized because it takes time to restore the authentication state when the app starts so any idea how to wait for it until it's initialized?
First of all, if the data entered is correct then we call login() function, then we send the verification code, when the code is sent inside the onCodeSent(), the method we call uploadSelectedImageToFirebaseStorage() to upload the user image then we call saveUserToDatabase() function, and here is the problem. Inside the saveUserToDatabase() function, the UID is always null no matter what I tried, am I missing something?
#file:Suppress("DEPRECATION")
class SignUpActivity : AppCompatActivity() {
private lateinit var binding: ActivitySignUpBinding
private lateinit var auth: FirebaseAuth
private lateinit var callbacks: PhoneAuthProvider.OnVerificationStateChangedCallbacks
lateinit var storedVerificationId: String
lateinit var resendToken: PhoneAuthProvider.ForceResendingToken
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySignUpBinding.inflate(LayoutInflater.from(this))
auth = FirebaseAuth.getInstance()
setContentView(binding.root)
val flProfilePicture = binding.frameProfilePicture
val tilUserName = binding.tilUserName
val tilPhoneNumber = binding.tilPhoneNumber
val startButton = binding.startButton
val currentUser = auth.currentUser
if (currentUser != null) {
val intent = Intent(this#SignUpActivity, MainChatsActivity::class.java)
startActivity(intent)
finish()
}
callbacks = object : PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
override fun onVerificationCompleted(credential: PhoneAuthCredential) { }
override fun onVerificationFailed(e: FirebaseException) { }
override fun onCodeSent(
verificationId: String,
token: PhoneAuthProvider.ForceResendingToken,
) {
Toast.makeText(baseContext, "Code Sent", Toast.LENGTH_SHORT).show()
storedVerificationId = verificationId
resendToken = token
val intent = Intent(applicationContext, AuthenticatePhoneActivity::class.java)
intent.putExtra("storedVerificationId", storedVerificationId)
uploadSelectedImageToFirebaseStorage()
startActivity(intent)
finish()
}
}
flProfilePicture.setOnClickListener {
val intent = Intent(Intent.ACTION_PICK)
intent.type = "image/*"
startActivityForResult(intent, 0)
}
startButton.setOnClickListener {
if (TextUtils.isEmpty(tilUserName.text.toString())) {
tilUserName.error = "Enter valid Name"
}
if (TextUtils.isEmpty(tilPhoneNumber.text.toString())) {
tilPhoneNumber.error = "Enter valid phone number"
} else {
val userName: String = tilUserName.text.toString()
val userPhoneNumber: String = tilPhoneNumber.text.toString()
login()
}
}
}
private var selectedProfilePicture: Uri? = null
#Deprecated("Deprecated in Java")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 0 && data != null) {
selectedProfilePicture = data.data
val bitmap = MediaStore.Images.Media.getBitmap(contentResolver, selectedProfilePicture)
val flProfilePicture = binding.frameProfilePicture
val selectedCircleFrame = binding.selectedPictureCircleFrame
selectedCircleFrame.setImageBitmap(bitmap)
flProfilePicture.alpha = 0f
}
}
private fun login() {
val mobileNumber = binding.tilPhoneNumber
val number = mobileNumber.text.toString().trim()
if (number.isNotEmpty()) {
sendVerificationCode(number)
} else {
mobileNumber.error = "Enter a valid phone number"
}
}
private fun sendVerificationCode(number: String) {
val options = PhoneAuthOptions.newBuilder(auth)
.setPhoneNumber(number)
.setTimeout(60L, TimeUnit.SECONDS)
.setActivity(this)
.setCallbacks(callbacks)
.build()
PhoneAuthProvider.verifyPhoneNumber(options)
}
private fun uploadSelectedImageToFirebaseStorage() {
if (selectedProfilePicture == null) {
return
}
val fileName = UUID.randomUUID().toString()
val ref = FirebaseStorage.getInstance().getReference("/images/$fileName")
ref.putFile(selectedProfilePicture!!)
.addOnSuccessListener {
ref.downloadUrl.addOnSuccessListener {
it.toString()
Log.d("SignUpActivity", "image uploaded successfully")
saveUserToDatabase(it.toString())
}
}
.addOnFailureListener {
saveUserToDatabase(it.toString())
}
}
private fun saveUserToDatabase(profileImageUrl: String) {
val tilUserName = binding.tilUserName.text.toString()
val tilPhoneNumber = binding.tilPhoneNumber.text.toString()
val uid = FirebaseAuth.getInstance().uid.toString()
val database = Firebase.database("https://blend-4a9e4-default-rtdb.asia-southeast1.firebasedatabase.app")
val myRef = database.getReference("/users/$uid")
val user = User(uid, tilPhoneNumber, tilUserName, profileImageUrl)
Log.d("currentUser", uid)
myRef.setValue(user)
.addOnFailureListener {
Toast.makeText(baseContext, "Something went wrong, try again.", Toast.LENGTH_SHORT).show()
}
}
}
Basically I have a activity which shows all the records input by the user. This uses a recyclerview. When the user clicks on an item row, it takes that info and displays it on the screen in another activity which is "Edit buy screen" . The user can edit the information and update it and then will be taken back to the "all records screen" upon success.
using getIntent, I managed to show the info on the screen. However when I try to update the info it doesnt change. According to debug. The var studentModel(Dataclass obj) is null on the second activity. This tells me that i need a way to bring the studentModel obj data from allrecords activity to the editScreen activity. Any way i can do this using getIntent or another way?
All records class
private lateinit var edName: EditText
private lateinit var edEmail: Button
private lateinit var edBuyAmount: EditText
private lateinit var edUseAmount: EditText
private lateinit var edReason: EditText
private lateinit var btnAdd: Button
private lateinit var btnView: Button
private lateinit var btnUpdate: Button
private lateinit var sqLiteHelper: SQLiteHelper
private lateinit var recyclerView: RecyclerView
private var adapter: StudentAdapter?=null
private var std:StudentModel?=null \<-------------This holds the data when the user clicks a row of data
#RequiresApi(Build.VERSION_CODES.N)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_all_recordpage)
val textView: TextView =findViewById(R.id.DateText)
val simpleDateFormat= SimpleDateFormat("yyyy/MM/dd\\n HH:mm", Locale.getDefault()).format(
Date()
)
val currentDateAndTime: String = simpleDateFormat.format(Date())
textView.text = currentDateAndTime
val button = findViewById\<Button\>(R.id.goBackToHome)
button.setOnClickListener{
val intent = Intent(this,MainMenu::class.java)
startActivity(intent)
}
initView()
initRecyclerView()
sqLiteHelper= SQLiteHelper(this)
//Show recycler view
val stdList = sqLiteHelper.getAllStudent()
Log.e("おっけ","${stdList.size}")
adapter?.setOnClickItem {
//購入・使用編集画面に遷移
**`if(it.buyamount > 0){`**
**`}else if (it.useamount > 0){`**
}else{
Toast.makeText(this,"エラーが発生しました",Toast.LENGTH_LONG).show()
}
}
adapter?.addItems(stdList)
adapter?.setOnClickDeleteItem{
deleteStudent(it.id)
}
}
private fun deleteStudent(id:Int){
val builder = AlertDialog.Builder(this)
builder.setMessage("データを削除してよろしいですか")
builder.setCancelable(true)
builder.setNegativeButton("いいえ"){dialog, \_ -\>
dialog.dismiss()
}
builder.setPositiveButton("はい"){dialog, \_ -\>
sqLiteHelper.deleteStudentById(id)
getStudents()
dialog.dismiss()
}
val alert = builder.create()
alert.show()
}
private fun updateStudent(){
val name = edName.text.toString()
val email = edEmail.text.toString()
val buyAmount = edBuyAmount.text.toString().toInt()
val useAmount = edUseAmount.text.toString().toInt()
val reason = edReason.text.toString()
//Check record not changed
if(name == std?.name && email == std?.email && buyAmount == std?.buyamount && useAmount == std?.useamount && reason == std?.reason){
Toast.makeText(this,"データが変更されてない", Toast.LENGTH_SHORT).show()
return
}
if(std == null) return
val std = StudentModel(id=std!!.id,name = name,email = email, buyamount = buyAmount, useamount = useAmount, reason = reason)
val status = sqLiteHelper.updateStudent(std)
if(status \> -1){
clearEditText()
getStudents()
}else{
Toast.makeText(this,"更新失敗した", Toast.LENGTH_SHORT).show()
}
}
private fun getStudents(){
val stdList = sqLiteHelper.getAllStudent()
Log.e("おっけ","${stdList.size}")
adapter?.addItems(stdList)
}
private fun addStudent(){
val name = edName.text.toString()
val email = edEmail.text.toString()
val buyAmount = edBuyAmount.text.toString().toInt()
val useAmount = edUseAmount.text.toString().toInt()
val reason = edReason.text.toString()
if(name.isEmpty()||email.isEmpty()|| buyAmount.toString().isEmpty() ||useAmount.toString().isEmpty() || reason.toString().isEmpty()){
Toast.makeText(this,"データを入力してください", Toast.LENGTH_SHORT).show()
}else{
val std = StudentModel(name = name, email=email, buyamount=buyAmount, useamount=useAmount, reason = reason)
val status = sqLiteHelper.insertStudent(std)
//Check Insert success or not success
if(status \> -2){
Toast.makeText(this,"データを追加しました。", Toast.LENGTH_SHORT).show()
clearEditText()
}else{
Toast.makeText(this,"データが保存されてないようです。", Toast.LENGTH_SHORT).show()
}
}
}
private fun clearEditText(){
edName.setText("")
edEmail.text = ""
edBuyAmount.setText("")
edUseAmount.setText("")
edReason.setText("")
edName.requestFocus()
}
private fun initRecyclerView(){
recyclerView.layoutManager=LinearLayoutManager(this)
adapter = StudentAdapter()
recyclerView.adapter=adapter
}
private fun initView(){
recyclerView=findViewById(R.id.recyclerView)
}
Buy details screen
\`class buyDetailsScreen : AppCompatActivity() {\`
private lateinit var edName: EditText
private lateinit var edEmail: Button
private lateinit var edBuyAmount: EditText
private lateinit var btnUpdate: Button
private lateinit var sqLiteHelper: SQLiteHelper
private lateinit var recyclerView: RecyclerView
private var adapter: StudentAdapter?=null
private var std:StudentModel?= null //Has nothing inside it . I need to get the info from first activity and put here
#SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_buy_details_screen)
val button = findViewById\<Button\>(R.id.goBackToMain)
button.setOnClickListener{
val intent = Intent(this,allRecordpage::class.java)
startActivity(intent)
}
val button2 = findViewById\<Button\>(R.id.goBacktoMain2)
button2.setOnClickListener{
val intent = Intent(this,allRecordpage::class.java)
startActivity(intent)
}
initView()
initRecyclerView()
sqLiteHelper= SQLiteHelper(this)
//Show recycler view
val stdList = sqLiteHelper.getAllStudent()
Log.e("おっけ","${stdList.size}")
adapter?.addItems(stdList)
edEmail = findViewById(R.id.edEmail)
edEmail.setOnClickListener{
clickDatePicker()
}
**edEmail.text = intent.getStringExtra("date")**
btnUpdate.setOnClickListener{
updateStudent()
val intent = Intent(this,allRecordpage::class.java)
startActivity(intent)
}
}
private fun clickDatePicker() {
val calender = Calendar.getInstance()
val year = calender.get(Calendar.YEAR)
val month = calender.get(Calendar.MONTH)
val day = calender.get(Calendar.DAY_OF_MONTH)
val datepicker = DatePickerDialog(this,
{ view,selectedYear,selectedMonth,selectedDay -\>
val selectedDate = "$selectedYear/${selectedMonth+1}/$selectedDay"
edEmail?.text=selectedDate
},
year,
month,
day
)
datepicker.datePicker.maxDate = System.currentTimeMillis()
datepicker.show()
}
private fun updateStudent(){
val name = edName.text.toString()
val email = edEmail.text.toString()
val buyAmount = edBuyAmount.text.toString().toInt()
//Check record not changed
if(name == std?.name && email == std?.email && buyAmount == std?.buyamount){
Toast.makeText(this,"データが変更されてない", Toast.LENGTH_SHORT).show()
return
}
if(std == null) return
val std = StudentModel(id=std!!.id,name = name,email = email, buyamount = buyAmount )
val status = sqLiteHelper.updateStudent(std)
if(status \> -1){
clearEditText()
getStudents()
}else{
Toast.makeText(this,"更新失敗した", Toast.LENGTH_SHORT).show()
}
}
private fun getStudents(){
val stdList = sqLiteHelper.getAllStudent()
Log.e("おっけ","${stdList.size}")
adapter?.addItems(stdList)
}
private fun clearEditText(){
edName.setText("")
edEmail.text = ""
edBuyAmount.setText(0)
edName.requestFocus()
}
private fun initRecyclerView(){
recyclerView.layoutManager= LinearLayoutManager(this)
adapter = StudentAdapter()
recyclerView.adapter=adapter
}
private fun initView(){
edName = findViewById(R.id.edName)
edEmail = findViewById(R.id.edEmail)
edBuyAmount = findViewById(R.id.edBuyAmount)
btnUpdate=findViewById(R.id.btnUpdate)
recyclerView=findViewById(R.id.recyclerView)
}
I expected to be able to update the std object but the Buy details activity private var std:StudentModel?= null contains nothing . how do i pass std:StudentModel from main activity to buy details activity so i can update/delete the record from SQlite
I need to login users with Google Sign On onto Firebase. But since I need to use the Calendar API, I have to do a custom login (and not the one provided through Firebase on default), as I need the Oauth refresh token - which is not provided by Firebase. I have looked at the docs but none seem to work, I am using the below code as of now... can anybody suggest how do I use the token obtained from Google to login/register with Firebase?
private const val TAG = "WelcomeActivity"
class WelcomeActivity : AppCompatActivity() {
var firebaseUser: FirebaseUser? = null
//For Google Sign In
val RC_SIGN_IN: Int = 9001
private lateinit var mGoogleSignInClient: GoogleSignInClient
lateinit var mGoogleSignInOptions: GoogleSignInOptions
private lateinit var firebaseAuth: FirebaseAuth
private var firebaseUserID: String = ""
private lateinit var refUsers: DatabaseReference
//get data from google signin in handlesigninresult
private var googleId = ""
private var googleFirstName = ""
private var googleLastName = ""
private var googleEmail = ""
private var googleProfilePicURL = ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_welcome)
// //For google sign in
// configureGoogleSignIn()
// setupUI()
// enablePersistence()
firebaseAuth = FirebaseAuth.getInstance()
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken("")
.requestEmail()
.build()
mGoogleSignInClient = GoogleSignIn.getClient(this, gso)
google_login.setOnClickListener {
signIn()
}
login_welcome.setOnClickListener {
val intent = Intent(this#WelcomeActivity, LoginActivity::class.java)
startActivity(intent)
finish()
}
}
private fun signIn() {
val signInIntent = mGoogleSignInClient.signInIntent
startActivityForResult(signInIntent, RC_SIGN_IN)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == RC_SIGN_IN) {
val task =
GoogleSignIn.getSignedInAccountFromIntent(data)
handleSignInResult(task)
}
}
private fun handleSignInResult(completedTask: Task<GoogleSignInAccount>) {
try {
val account = completedTask.getResult(
ApiException::class.java
)
// Signed in successfully
googleId = account?.id ?: ""
Log.i("Google ID", googleId)
googleFirstName = account.givenName ?: ""
Log.i("Google First Name", googleFirstName)
googleLastName = account?.familyName ?: ""
Log.i("Google Last Name", googleLastName)
googleEmail = account?.email ?: ""
Log.i("Google Email", googleEmail)
val googleIdToken: String = account?.idToken ?: ""
Log.i("Google ID Token", googleIdToken)
googleProfilePicURL = account?.photoUrl.toString()
Log.i("Google Profile Pic URL", googleProfilePicURL)
firebaseAuthWithGoogle(googleIdToken)
} catch (e: ApiException) {
// Sign in was unsuccessful
Log.e(
"failed code=", e.statusCode.toString()
)
}
}
private fun enablePersistence() {
// [START rtdb_enable_persistence]
Firebase.database.setPersistenceEnabled(true)
// [END rtdb_enable_persistence]
}
private fun firebaseAuthWithGoogle(idToken: String) {
val credential = GoogleAuthProvider.getCredential(idToken, null)
firebaseAuth.signInWithCredential(credential)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
// Sign in success, update UI with the signed-in user's information
Log.d(TAG, "signInWithCredential:success")
firebaseUserID = firebaseAuth.currentUser!!.uid
refUsers = FirebaseDatabase.getInstance().reference.child("Users").child(firebaseUserID)
refUsers.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(p0: DataSnapshot) {
if (p0.exists()) {
val user: Users? = p0.getValue(Users::class.java)
//Check if user exists in the database
if (user!!.getFirstName() != null) {
val intent = Intent(
this#WelcomeActivity,
IntroSplashScreen::class.java
)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
finish()
} else {
val usersHashMap = HashMap<String, Any>()
usersHashMap["uid"] = firebaseUserID
usersHashMap["firstname"] = googleFirstName
usersHashMap["surname"] = googleLastName
usersHashMap["profile"] = googleProfilePicURL
usersHashMap["primaryEmail"] = googleEmail
usersHashMap["search"] =
googleFirstName.toLowerCase(Locale.ROOT)
refUsers.updateChildren(usersHashMap)
.addOnCompleteListener {
if (task.isSuccessful) {
val intent = Intent(
this#WelcomeActivity,
NewProfileData::class.java
)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
finish()
}
}
}
}
}
override fun onCancelled(error: DatabaseError) {
TODO("Not yet implemented")
}
})
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "signInWithCredential:failure", task.exception)
// ...
}
// ...
}
}
private fun refreshIdToken() {
// Attempt to silently refresh the GoogleSignInAccount. If the GoogleSignInAccount
// already has a valid token this method may complete immediately.
//
// If the user has not previously signed in on this device or the sign-in has expired,
// this asynchronous branch will attempt to sign in the user silently and get a valid
// ID token. Cross-device single sign on will occur in this branch.
mGoogleSignInClient.silentSignIn()
.addOnCompleteListener(
this
) { task -> handleSignInResult(task) }
}
override fun onStart() {
super.onStart()
//Checks if the Google IDToken has expired, if yes it refreshes by SilentSign in and generates new Firebase Token
refreshIdToken()
//Checks if user is logged in to firebase
firebaseUser = FirebaseAuth.getInstance().currentUser
//If logged in then sends to MainActivity
if (firebaseUser != null) {
startActivity(IntroSplashScreen.getLaunchIntent(this))
finish()
}
}
override fun onResume() {
super.onResume()
refreshIdToken()
}
}
My method of checking if the user exists was incorrect with the currect process being to put the check on Datasnapshot exits or not. If exists then login else register.
How can I retrieve data with child* from Firebase Database and populate an User object class.
Firebase example:
users
uid : 131232
firstName : John
lastName : Doe
location
lat* : 15.2512312
lon* : -12.1512321
chats
-k1231* : true
-k1285* : true
and after having retrieved the data being able to use ie.: User.firstName or User.location.lat etc.
Thank you in advance.
As Sam Stern mentioned in his answer, it's best to create a representation for each class separately. I'll write you the corresponding classes in Kotlin.
This is the User class:
class User (
val firstName: String = "",
val lastName: String = "",
val userLocation: UserLocation? = null
)
And this is the UserLocation class:
class UserLocation (
val lat: Int = 0,
val lng: Int = 0
)
to query this User 1332 and cast it to the User.class object
Please use the following lines of code:
val uid = FirebaseAuth.getInstance().currentUser!!.uid
val rootRef = FirebaseDatabase.getInstance().reference
val uidRef = rootRef.child("users").child(uid)
val valueEventListener = object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
val user = dataSnapshot.getValue(User::class.java)
Log.d(TAG, "Lat/Lng: " + user!!.userLocation!!.lat + ", " + user.userLocation!!.lng);
}
override fun onCancelled(databaseError: DatabaseError) {
Log.d(TAG, databaseError.message) //Don't ignore errors!
}
}
uidRef.addListenerForSingleValueEvent(valueEventListener)
In which the uid should hold a value like 131232. The output in your logcat will be:
Lat/Lng: 15.2512312, -12.1512321
In the same way you can get: user!!.firstName and user!!.lastName.
Your best bet is to create multiple custom classes:
class User {
public String firstName;
public String lastName;
public UserLocation location;
}
...
class UserLocation {
public double lat;
public double lon;
}
Then you can deserialize the whole thing to User.