告诉我任何更好的方法来将Realm数据库与Firebase同步

时间:2018-02-06 15:39:10

标签: android multithreading firebase realm rx-java

我正在开发一个项目,我正在使用Realm数据库和Firebase和RxJava 2.在我的项目中,我有用户活动,它将列出存储在Firebase数据库中的所有注册用户。此外,我必须存储所有注册用户进入Realm数据库(如果Internet不可用,请注册)。因此,每当用户启动活动时,我的observable将逐个运行并获取所有注册用户并将它们存储在Realm数据库中,并且当observable完成时,数据将填充在Realm Database的recyclerview上。这是我的代码

class AllUsers : AppCompatActivity(){
private var recyclers : RecyclerView ?= null
private var toolbars : Toolbar ?= null
private var toolbar_text : TextView ?= null
private var userAdapter : UserAdapter ?= null
private var userModelList : ArrayList<RequestPojo> ?= null
private var databaseReference : DatabaseReference ?= null
private var compositeDisposable : CompositeDisposable ?= null
private var firebaseAuth : FirebaseAuth ?= null
private var currentUserUid : String ?= null
private var realm : Realm?= null
private var requestController : RequestsController ?= null
private var suggestedFriendsController : SuggestedFriendsController ?= null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.allusers)
    initialize()
}
private fun initialize(){
    compositeDisposable = CompositeDisposable()
    userModelList = ArrayList()
    toolbars = findViewById(R.id.toolbar)
    recyclers = findViewById(R.id.recycler)
    toolbar_text = toolbars?.findViewById(R.id.toolbar_text1)
    toolbar_text?.visibility = View.VISIBLE
    toolbar_text?.text = "Users"
    setSupportActionBar(toolbars)
    supportActionBar?.setDisplayHomeAsUpEnabled(true)
    getSupportActionBar()?.setHomeButtonEnabled(true)
    userAdapter = UserAdapter(this,userModelList)
    recyclers?.setHasFixedSize(true)
    var recyclerlayoutmanager = LinearLayoutManager(this)
    recyclers?.setLayoutManager(recyclerlayoutmanager)
    val dividerItemDecoration = DividerItemDecoration(recyclers?.getContext(),
            recyclerlayoutmanager.orientation)
    recyclers?.addItemDecoration(dividerItemDecoration)
    recyclers?.itemAnimator = DefaultItemAnimator()
    recyclers?.setAdapter(userAdapter)
    firebaseAuth = FirebaseAuth.getInstance()
    currentUserUid = firebaseAuth?.currentUser?.uid
    databaseReference = FirebaseDatabase.getInstance().reference
    databaseReference?.keepSynced(true)
    realm = Realm.getDefaultInstance()
    requestController = RequestsController()
    suggestedFriendsController = SuggestedFriendsController()
}

override fun onStart() {
    super.onStart()
    loadUsersFromFirebase()
    populateDataFromRealm()
}

fun populateDataFromRealm(){
    suggestedFriendsController?.getAllAsync()
            ?.subscribe({
                t: RealmSuggestedFriends? ->  var requestPojo = RequestPojo()
                requestPojo?.email = t?.friendEmail
                requestPojo?.image = t?.friendImage
                requestPojo?.name = t?.friendName
                requestPojo?.status = t?.friendStatus
                requestPojo?.thumb_image = t?.friendThumbImage
                requestPojo?.uid = t?.friendUid
                userAdapter?.addData(requestPojo)
            },{
                t: Throwable? ->  t?.printStackTrace()
            },{

            },{
                t: Disposable? ->compositeDisposable?.add(t!!)
            })
}

fun loadUsersFromFirebase(){
    Observable.create<DataSnapshot>{ emitter ->
        databaseReference
                ?.child("Users")
                ?.addChildEventListener(object : ChildEventListener{
                    override fun onCancelled(p0: DatabaseError?) {}
                    override fun onChildMoved(p0: DataSnapshot?, p1: String?) {}
                    override fun onChildChanged(p0: DataSnapshot?, p1: String?) {}
                    override fun onChildAdded(p0: DataSnapshot?, p1: String?) {
                        if(!emitter.isDisposed){
                            if (!p0?.key?.equals(currentUserUid)!!){
                                emitter.onNext(p0)
                            }
                        }
                    }
                    override fun onChildRemoved(p0: DataSnapshot?) {}
                })
    }.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Observer<DataSnapshot>{
                override fun onComplete() {}

                override fun onNext(t: DataSnapshot) {
                        val userModel = t.getValue(RequestPojo::class.java)
                        userModel?.uid = t.key

                    suggestedFriendsController?.addSuggestedFriends(userModel)
                }
                override fun onSubscribe(d: Disposable) {
                compositeDisposable?.add(d)
                }
                override fun onError(e: Throwable) {
                    e.printStackTrace()
                }
            })
}

private fun showMessage(message : String?) {
    Toast.makeText(this@AllUsers,message,Toast.LENGTH_SHORT).show()
}

override fun onRestart() {
    super.onRestart()
    userModelList?.clear()
    userAdapter?.notifyDataSetChanged()
}

override fun onBackPressed() {
    super.onBackPressed()
    finish()
}

override fun onStop() {
    super.onStop()
    compositeDisposable?.clear()
}

override fun onDestroy() {
    super.onDestroy()
    realm?.close()
}

}

这是我的Realm Controller,它将涵盖所有存储,检索和更新数据的Realm方法。

class SuggestedFriendsController {

fun addSuggestedFriends(requestPojo: RequestPojo?) {
    Realm.getDefaultInstance().use { r->
            r?.executeTransaction { realm ->
                val realmFriends = RealmSuggestedFriends()
                realmFriends.friendEmail = requestPojo?.email
                realmFriends.friendImage = requestPojo?.image
                realmFriends.friendName = requestPojo?.name
                realmFriends.friendStatus = requestPojo?.status
                realmFriends.friendThumbImage = requestPojo?.thumb_image
                realmFriends.friendUid = requestPojo?.uid
                realmFriends.requestSent = "No"
                realm.insertOrUpdate(realmFriends)
            }
    }
}

fun getSuggestedFriendSync(realm : Realm?,uid : String?): RealmSuggestedFriends? =
    realm?.where(RealmSuggestedFriends::class.java)?.equalTo("friendUid",uid)?.findFirst()

fun getRequestStateAsync(uid: String?) =
    Observable.create<String> { emitter ->
        val real = Realm.getDefaultInstance()
        try{
            val res = real?.where(RealmSuggestedFriends::class.java)
                        ?.equalTo("friendUid", uid)
                        ?.findFirst()
            emitter.onNext(res?.requestSent!!)
            emitter.onComplete()
        }catch(e : Exception){
           emitter.onError(Throwable("read failed"))
        }
        finally {
            real?.close()
        }
    }.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())

fun getAllAsync() = Observable.create<List<RealmSuggestedFriends>> { emitter ->
    Realm.getDefaultInstance().use { realm ->
        val results = realm?.where(RealmSuggestedFriends::class.java)
                ?.findAll()
        emitter.onNext(realm?.copyFromRealm(results)!!)
    }
}.flatMapIterable { list -> list }
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())

fun updateSuggestedFriendAsync(uid: String?, request_type: String?) =
        Single.create<String>{emitter ->
            Realm.getDefaultInstance().use { realm ->
                try {
                    realm?.beginTransaction()
                    var suggested = realm.where(RealmSuggestedFriends::class.java)
                            .equalTo("friendUid", uid)
                            .findFirst()!!
                    suggested.requestSent = request_type
                   var d = realm.copyToRealmOrUpdate(suggested)

                    realm?.commitTransaction()
                    emitter.onSuccess(d?.requestSent!!)
                }catch (e : Exception){
                    emitter.onError(Throwable(e.message))
                    e.printStackTrace()
                }
            }
        }
        .subscribeOn(AndroidSchedulers.mainThread())

}

现在每当我开始我的活动时,我的observable将运行并从Firebase获取每个用户并将它们存储在Realm数据库中。

  1. 那么有没有更好的方法可以让我只在注册新用户时运行observable,如果没有注册新用户,那么我的observable不应该运行。
  2. 2还有更好的方法可以将我的Realm数据库与Firebase服务器同步。

    请建议我......提前谢谢。

0 个答案:

没有答案