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

Android中Firestore读取后ArrayList为空 无法校验昵称重复问题求助

问题根源

空列表问题是Firestore 异步执行机制导致的:

  • addSnapshotListener 属于异步回调接口,调用后不会阻塞当前主线程,会立刻返回,主线程会继续向下执行你写的昵称校验逻辑
  • 此时 Firestore 还未完成远程数据拉取,onEvent 回调中给nicklist添加数据的代码还没执行,所以判断时列表必然是空的

优化修正方案

  • 单次校验昵称不需要使用实时监听addSnapshotListener,改用get()做单次请求即可,避免重复注册监听导致内存泄漏
  • 所有昵称校验、数据写入、页面跳转的逻辑必须放到数据请求成功的回调内部执行,保证执行校验时已经拿到全量的已存在昵称列表
  • 不需要将nicklist设为全局变量,每次校验时在回调内创建新列表即可,避免旧缓存数据导致校验错误

修改后的核心代码

public void kayıt(View view) {
    String nick = nickText.getText().toString();
    // 先做非空校验
    if (nick.trim().isEmpty()) {
        Toast.makeText(this, "请输入有效昵称", Toast.LENGTH_SHORT).show();
        return;
    }
    CollectionReference collectionReference = firestore.collection("Kullanıcılar ve Skorlar");
    // 单次请求获取所有昵称数据
    collectionReference.get().addOnCompleteListener(task -> {
        if (task.isSuccessful()) {
            ArrayList<String> nickList = new ArrayList<>();
            for (QueryDocumentSnapshot doc : task.getResult()) {
                String existNick = doc.getString("nick");
                if (existNick != null) {
                    nickList.add(existNick);
                }
            }
            // 校验逻辑放到回调内执行
            if (nickList.contains(nick)) {
                Toast.makeText(NickName.this, "Bu Kullanıcı İsmi Zaten Mevcut", Toast.LENGTH_SHORT).show();
            } else {
                userid = mAuth.getCurrentUser().getUid();
                DocumentReference documentReference = firestore.collection("Kullanıcılar ve Skorlar").document(userid);
                Map<String, Object> userData = new HashMap<>();
                userData.put("nick", nick);
                userData.put("email", email);
                userData.put("skor", 0);
                documentReference.set(userData)
                        .addOnSuccessListener(unused -> Log.d("Tag", "Veri alındı" + userid))
                        .addOnFailureListener(e -> Log.d("Tag", "işlem başarısız" + e.toString()));
                Intent intent = new Intent(NickName.this, Secimekrani.class);
                startActivity(intent);
                finish();
            }
        } else {
            Log.e("tag", "数据拉取失败", task.getException());
            Toast.makeText(NickName.this, "网络请求失败,请重试", Toast.LENGTH_SHORT).show();
        }
    });
}

内容的提问来源于stack exchange,提问作者Yusuf Aydın

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 00:54:01