📅  最后修改于: 2021-01-02 03:37:12             🧑  作者: Mango
在本节中,我们将学习如何在android应用程序中读写Firebase实时数据库。在上一节中,我们创建了一个android应用程序,并为其添加了Firebase。我们已经实现了所有必需的库和插件。在命名fir-realtimedatabaseexam-60676之前,我们已经创建了一个数据库。
在代码内部,我们必须使用getInstance()方法检索数据库的实例,然后引用我们必须写入的位置。我们必须记住,数据库是围绕JSON节点组织的。
我们将一个异步侦听器附加到引用。对于数据的初始状态,将一次触发侦听器,而在数据更改时,会再次触发该侦听器。
Private lateinit var database:DatabaseReference
//??.
Database=FirebaseDatabase.getInstance().reference
myRef=database.getReference("message")
myRef.setValue("Hello,World!")
我们可以保存数据库的一系列数据类型(String,Long,Double和Boolean等)。这样,我们可以保存Kotlin对象。当我们保存一个对象时,来自任何获取器的响应都将被保存为该位置和JSON格式的子级。
将用户定义为自定义java对象的类包含一个默认构造函数,该构造函数不带任何参数,并且具有要分配的属性的公共getter。
我们将编写一个实际的对象,即用户对象。 User.kotlin类和Signing或register活动中的用户编写该对象。因此,当我们使用Kotlin对象时,对象的内容会以嵌套方式自动映射到子位置。使用对象,我们使我们的代码更具可读性,更易于维护和编写对象。
data class User(
var username:String?=null,
var email:String?=null
)
我们可以使用setVaue()函数添加用户对象
private fun writeNewUser(userId:String, name:String,email:String?)){
val user=User(name,email)
database.child("users").child(userId).setValue(user)
}
我们可以使用设置值方法来写一个新用户。我们仍然可以更新子级而无需重写整个对象。
databse.child("users").child(userId).child("username").setValue(name)
要读取路径中的数据并在数据更改时侦听任何更改,我们必须使用addValueEventListener()或addListenerForSingleValueEvent()方法将ValueEventListener添加到数据库引用中。这两种方法会将valueEventListener添加到DatabaseReference。
我们可以使用onDataChange()方法读取给定路径上内容的静态快照。附加了侦听器后将触发一次,并且每次数据更改(包括子级)都会再次触发。它传递一个快照,其中包含该位置的所有数据,包括子数据。如果没有数据,则当我们调用exist()时,快照将返回false;当我们调用getValue()时,快照将返回null。
在某些情况下,我们可能希望调用一次回调,然后立即将其删除。对于仅需加载一次且预计不会频繁更改或需要主动监听的数据很有用。监听确实有一些开销,因此,如果我们只需要阅读一次,则不需要执行回调。
例如,初始化用户界面元素时,我们不希望更改它,但是仅在需要读取一部分数据时才想使用addListenerForSingleValueEvent()。它不会一次又一次地改变法律。
例:
我们正在实现一个android应用程序。这是一个用户登录和注册应用程序,具有三个xml文件和四个Kotlin文件。 activity_main.xml用于注册页面。 activity_signing.xml用于登录,activity_welcome.xml用于从数据库检索数据。同样,有四个Kotlin文件,即MainActivity,Signing,welcome和User。
当用户注册自己时,会将他们添加到firebase控制台用户部分,并将与他们相对应的数据存储到数据库中。签名功能与我们在身份验证部分中所做的相同。用户成功注册或注册后,将切换到欢迎页面,在该页面上可以找到他的数据。
activity_main.xml,activity_signing和activity_welcome
MainActivity.kt
package com.example.firebaserealtimedatabase
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.widget.Toast
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.DatabaseReference
import com.google.firebase.database.FirebaseDatabase
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
//Creating member variables of FirebaseAuth
private var mAuth: FirebaseAuth?=null
//Creating member variables of FirebaseDatabase and DatabaseReference
private var mFirebaseDatabaseInstances: FirebaseDatabase?=null
private var mFirebaseDatabase: DatabaseReference?=null
//Creating member variable for userId and emailAddress
private var userId:String?=null
private var emailAddress:String?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//Get Firebase Instances
mAuth=FirebaseAuth.getInstance()
//Get instance of FirebaseDatabase
mFirebaseDatabaseInstances= FirebaseDatabase.getInstance()
//if already logged in go to sign in screen
if(mAuth!!.currentUser!=null){
startActivity(Intent(this,welcome::class.java))
finish()
}
}
fun onLoginClicked(view: View) {
startActivity(Intent(this,Signing::class.java))
finish()
}
//calling onRegisterClicked button
fun onRegisterClicked(view: View) {
//Validation checking
if(TextUtils.isEmpty(username.text.toString())){
Toast.makeText(applicationContext,"Enter Username!",Toast.LENGTH_LONG).show()
}
if(TextUtils.isEmpty(email.text.toString())){
Toast.makeText(applicationContext,"Enter email address!",Toast.LENGTH_LONG).show()
}
if(TextUtils.isEmpty(password.text.toString())){
Toast.makeText(applicationContext,"Enter password!",Toast.LENGTH_LONG).show()
}
if(password.text.toString().length<6){
Toast.makeText(applicationContext,"Password is too short",Toast.LENGTH_LONG).show()
}
//Making progressBar visible
progressBar!!.visibility=View.VISIBLE
//creating user
mAuth!!.createUserWithEmailAndPassword(email.text.toString(),password.text.toString())
.addOnCompleteListener(this){task ->
Toast.makeText(this,"createUserWithEmail:onComplete"+task.isSuccessful,Toast.LENGTH_SHORT).show()
progressBar.visibility=View.GONE
// When the sign-in is failed, a message to the user is displayed. If the sign-in is successful, auth state listener will get notified, and logic to handle the signed-in user can be handled in the listener.
if(task.isSuccessful){
//Getting reference to ?users? node
mFirebaseDatabase=mFirebaseDatabaseInstances!!.getReference("users")
//Getting current user from FirebaseAuth
val user=FirebaseAuth.getInstance().currentUser
//add username, email to database
userId=user!!.uid
emailAddress=user.email
//Creating a new user
val myUser=User(username.text.toString(),emailAddress!!)
//Writing data into database using setValue() method
mFirebaseDatabase!!.child(userId!!).setValue(myUser)
startActivity(Intent(this,welcome::class.java))
finish()
}else{
Toast.makeText(this,"Authentication Failed"+task.exception,Toast.LENGTH_SHORT).show()
Log.e("MyTag",task.exception.toString())
}
}
}
}
welcome.kt
package com.example.firebaserealtimedatabase
import android.content.Intent
import android.nfc.Tag
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.constraintlayout.solver.widgets.Snapshot
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.*
import kotlinx.android.synthetic.main.activity_main.*
class welcome : AppCompatActivity() {
//Creating member variables
private var mFirebaseDatabase: DatabaseReference?=null
private var mFirebaseInstance: FirebaseDatabase?=null
var userId:String?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_welcome)
//Getting instances of FirebaseDatabase
mFirebaseInstance= FirebaseDatabase.getInstance()
//get reference to 'users' node
mFirebaseDatabase=mFirebaseInstance!!.getReference("users")
val user=FirebaseAuth.getInstance().currentUser
//add it only if it is not saved to database
if (user != null) {
userId=user.uid
}
addUserChangeListener()
}
private fun addUserChangeListener(){
//User data change Listener
mFirebaseDatabase!!.child(userId!!).addValueEventListener(object: ValueEventListener{
override fun onDataChange(dataSnapshot: DataSnapshot){
val user=dataSnapshot.getValue(User::class.java)
//Check for null
if(user==null){
Log.e(TAG,"User data is null")
return
}
Log.e(TAG,"User data is changed!"+user.name+","+user.email)
//Display newly updated name and email
email.setText(user.email)
username.setText(user.name)
}
override fun onCancelled(error: DatabaseError){
//Failed to read value
Log.e(TAG,"Failed to read user",error.toException())
}
})
}
fun onLogout(view: View) {
FirebaseAuth.getInstance().signOut()
startActivity(Intent(this, MainActivity::class.java))
}
companion object{
private val TAG=database::class.java.simpleName
}
}
User.kt
package com.example.firebaserealtimedatabase
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class User{
lateinit var name:String
lateinit var email:String
//Default constructor required for calls to
//DataSnapshot.getValue(User.class)
constructor(){
}
constructor(name:String,email:String){
this.name=name
this.email=email
}
}
签名
package com.example.firebaserealtimedatabase
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.widget.Toast
import com.google.firebase.auth.FirebaseAuth
import kotlinx.android.synthetic.main.activity_main.*
class Signing : AppCompatActivity() {
private var mAuth: FirebaseAuth?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_signing)
//Initialize Firebase Auth
mAuth=FirebaseAuth.getInstance()
}
public override fun onStart() {
super.onStart()
//if user logged in, go to sign in screen
if(mAuth!!.currentUser!=null){
startActivity(Intent(this,welcome::class.java))
finish()
}
}
override fun onResume() {
super.onResume()
progressBar.visibility= View.GONE
}
fun loginButtonClicked(view: View){
if(TextUtils.isEmpty(email.text.toString())){
Toast.makeText(applicationContext,"Enter Username!", Toast.LENGTH_LONG).show()
return
}
if(TextUtils.isEmpty(password.text.toString())){
Toast.makeText(applicationContext,"Enter password!", Toast.LENGTH_LONG).show()
return
}
progressBar.visibility=View.VISIBLE
//Authenticate user
mAuth!!.signInWithEmailAndPassword(email.text.toString(),password.text.toString())
.addOnCompleteListener(this){task ->
progressBar.visibility=View.GONE
if(task.isSuccessful){
val intent=Intent(this,welcome::class.java)
startActivity(intent)
finish()
}else{
if(password.text.toString().length<6){
password.error="Password is too short, enter minimum 6 characters"
}
Toast.makeText(this,"Authentication Failed"+task.exception,Toast.LENGTH_SHORT).show()
}
}
}
}