📌  相关文章
📜  Firebase实时数据库读写

📅  最后修改于: 2021-01-02 03:37:12             🧑  作者: Mango

Firebase:实时数据库读写

在本节中,我们将学习如何在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.kt,Signing.kt)

我们将编写一个实际的对象,即用户对象。 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()
                }
            }
    }
}