You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

安卓Firebase实时数据库首次安装时addListenerForSingleValueEvent未触发求助

问题描述

首次安装应用时,通过Firebase Realtime Database获取数据失败,addListenerForSingleValueEvent方法未被调用;重启应用后数据可正常加载。相关代码如下:

private fun fetchData(onComplete: ((Boolean) -> Unit)?=null) {
    val database = FirebaseDatabase.getInstance().reference
    var ref: DatabaseReference? = null
    if (context?.packageName?.contains(".dev") == false) {
        ref = database.child("sticker_packs")
    } else {
        ref = database.child("sticker_packs_devs")
        Timber.d("it debug mode")
    }
    val phoneQuery = ref.orderByChild("identifier")
    val firebaseList = ArrayList<StickerPack>()
    phoneQuery.addListenerForSingleValueEvent(object : ValueEventListener {
        override fun onDataChange(dataSnapshot: DataSnapshot) {
            for (singleSnapshot in dataSnapshot.children) {
                Timber.e(TAG, "onDataChange: ${singleSnapshot.child("stickers").value}")
                val stickerPacks: StickerPack? = singleSnapshot.getValue<StickerPack>()

                stickerspack = stickerPacks
                stickers = stickerPacks
                val unzipLocation = "${path}/${stickerPacks?.pack_id}"

                if (stickerPacks != null) {
                    Timber.d("zipfilepath ${stickerPacks.zip_file}")
                }
                val tryIconPath = "$unzipLocation/try"
                val trypath = File(tryIconPath)
                val trayFile = trypath.listFiles()
                var tryiconImage = ""
                trayFile?.forEach {
                    if (it.name.contains(".png")) {
                        tryiconImage = it.name
                    }
                    Timber.d("try icon g $tryiconImage")
                }
                stickerPacks?.tray_image_file = tryiconImage
                val pkg = "${Package_Head}${PACKAGE_NAME}"
                stickerPacks?.publisherEmail = getString(R.string.feedback_email)
                stickerPacks?.publisherWebsite = getString(R.string.privacy_policy_link)
                stickerPacks?.privacyPolicyWebsite = getString(R.string.privacy_policy_link)
                stickerPacks?.licenseAgreementWebsite =
                    getString(R.string.privacy_policy_link_1)
                stickerPacks?.isWhitelisted = true
                stickerPacks?.android_play_store_link = pkg
                if (stickerPacks != null) {
                    firebaseList.add(stickerPacks)
                }
            }
            Timber.e(TAG, "onDataChangecache: ${firebaseList.size}")
            Timber.e(TAG, "arraylist1: ${firebaseList.size}")
            val getListFromMainActivity = Hawk.get("listfromactivity", ArrayList<StickerPack>())
            Timber.d("CheckIfNull ${getListFromMainActivity.size}")
            if (getListFromMainActivity.isNullOrEmpty() && getListFromMainActivity.size <= 0) {
                onComplete?.invoke(false)
            }else{
                onComplete?.invoke(true)
                context?.let {
                    adapter?.setData(
                        it, getListFromMainActivity, requireActivity(), this@StickersFragment
                    )
                }
            }
            Hawk.put("sticker_packs", firebaseList)
            view?.linlaHeaderProgress?.visibility = View.GONE
            if (view?.linlaHeaderProgress?.visibility == View.GONE) {
                //spinnerDialog()
            }
            Timber.e(TAG, "onDataChe0:$dataSnapshot ")
        }

        override fun onCancelled(databaseError: DatabaseError) {
            Timber.e(TAG, "onCancelled", databaseError.toException())
        }
    })
}

class StickerPack : Parcelable {
    var pack_id: String=""
    var pack_Name: String=""
    var publisher: String=""
    var tray_image_file: String=""
    var publisherEmail: String="" //exclude
    var publisherWebsite: String="" //exclude
    var privacyPolicyWebsite: String="" //exclude
    var licenseAgreementWebsite: String="" //exclude
    var iosAppStoreLink: String="" //exclude
    private var stickers: List<Sticker>? = null
    var totalSize: Long = 0
        private set
    var android_play_store_link: String=""
    var isWhitelisted = false //exclude
    var animated_sticker_pack:Boolean= false
    var zip_file: String?=null
}
解决方案

1. 确保Firebase在Application级别初始化

避免在Fragment/Activity中延迟初始化导致实例未就绪:

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        FirebaseApp.initializeApp(this)
    }
}

在AndroidManifest.xml中注册该Application:

<application
    android:name=".MyApplication"
    <!-- 其他配置 -->
>
</application>

2. 校验fetchData调用时机

确保在context完全可用后调用该方法:

  • 如果是Fragment,在onViewCreated或onResume中调用
  • 如果是Activity,在onStart或onResume中调用

3. 增加ref非空判断与数据同步

避免因context为空导致ref未初始化,同时强制同步数据确保首次安装时能从网络获取:

private fun fetchData(onComplete: ((Boolean) -> Unit)?=null) {
    val database = FirebaseDatabase.getInstance().reference
    val ref = if (context?.packageName?.contains(".dev") == false) {
        database.child("sticker_packs")
    } else {
        database.child("sticker_packs_devs").also {
            Timber.d("it debug mode")
        }
    }

    // 新增非空判断,避免空指针
    if (ref == null) {
        Timber.e(TAG, "Database reference is null, context might be unavailable")
        onComplete?.invoke(false)
        view?.linlaHeaderProgress?.visibility = View.GONE
        return
    }

    val phoneQuery = ref.orderByChild("identifier")
    // 强制同步数据,确保首次安装时能从网络获取
    phoneQuery.keepSynced(true)
    val firebaseList = ArrayList<StickerPack>()
    
    // 剩余代码保持不变
}

4. 排查数据库规则与网络权限

  • 确认Firebase Realtime Database的读写规则允许当前应用访问(首次安装时若规则限制,onCancelled会触发,可查看日志)
  • 检查应用是否已声明INTERNET权限:
<uses-permission android:name="android.permission.INTERNET" />

5. 优化onDataChange逻辑

首次安装时Hawk.get("listfromactivity")必然为空,应直接使用从Firebase获取的firebaseList:

// 替换原判断逻辑
if (firebaseList.isEmpty()) {
    onComplete?.invoke(false)
} else {
    onComplete?.invoke(true)
    context?.let {
        adapter?.setData(it, firebaseList, requireActivity(), this@StickersFragment)
    }
}
Hawk.put("sticker_packs", firebaseList)
// 同时更新Hawk中的"listfromactivity",避免后续依赖旧数据
Hawk.put("listfromactivity", firebaseList)

内容的提问来源于stack exchange,提问作者user19499909

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 03:45:35