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

Firebase实时数据库匹配本地联系人存入HashMap失败求助

问题原因分析

核心问题在于Firebase Realtime Database的操作是异步的,你的exists()方法在返回结果时,Firebase的回调还没执行完成,导致判断逻辑完全失效:

当你调用exists(number)时,方法会立刻返回numberF[0]的初始值(空字符串),而onDataChange回调要等网络请求完成后才会执行。这时候exists(number).equalsIgnoreCase(number)的判断永远不成立,自然不会执行contactList.put()。

修复方案

把联系人的判断和HashMap添加逻辑直接放到Firebase的异步回调中,同时优化监听方式避免不必要的资源消耗:

@SuppressLint("Range")
private void getContacts() {
    @SuppressLint("Recycle")
    Cursor cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
            null, null, null, null);
    while (cursor.moveToNext()) {
        String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
        String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
        number = number.trim();

        Pattern p = Pattern.compile(
                "^(\\+\\d{1,3}( )?)?((\\(\\d{1,3}\\))|\\d{1,3})[- .]?\\d{3,4}[- .]?\\d{4}$");

        Matcher m = p.matcher(number);

        if (m.find()) {
            // 直接调用异步检查方法,传入姓名和号码
            checkAndAddContact(number, name);
        }
    }
}

private void checkAndAddContact(String number, String name) {
    if (number.length() > 10 && number.length() <= 15) {
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("users");
        // 使用addListenerForSingleValueEvent,仅查询一次数据,避免持续监听
        reference.child(number).addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                if (snapshot.exists()) {
                    String numberDB = snapshot.child("number").getValue(String.class);
                    if (numberDB != null && numberDB.equalsIgnoreCase(number)) {
                        Log.i("Does match:", number);
                        contactList.put(number, name);
                        // 必须在主线程更新RecyclerView
                        runOnUiThread(() -> yourRecyclerViewAdapter.notifyDataSetChanged());
                    }
                } else {
                    Log.wtf("Does not match:", number);
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                Log.wtf("Check failed:", error.getMessage());
            }
        });
    } else {
        Log.wtf("Invalid number:", number);
    }
}
关键优化点
  1. 异步逻辑迁移:将HashMap的添加操作移到onDataChange回调内,确保只有在拿到数据库返回结果后才执行判断和添加
  2. 监听方式优化:用addListenerForSingleValueEvent替代addValueEventListener,只查询一次数据,避免持续监听造成的资源浪费
  3. UI线程更新:Firebase回调在后台线程执行,更新RecyclerView必须切换到主线程,否则会抛出异常
  4. 格式一致性:确保联系人号码的格式和数据库中存储的格式完全一致(比如统一带国家码、去掉特殊字符),否则会出现匹配失败的情况

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 23:27:33