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); } }
关键优化点
- 异步逻辑迁移:将HashMap的添加操作移到
onDataChange回调内,确保只有在拿到数据库返回结果后才执行判断和添加 - 监听方式优化:用
addListenerForSingleValueEvent替代addValueEventListener,只查询一次数据,避免持续监听造成的资源浪费 - UI线程更新:Firebase回调在后台线程执行,更新RecyclerView必须切换到主线程,否则会抛出异常
- 格式一致性:确保联系人号码的格式和数据库中存储的格式完全一致(比如统一带国家码、去掉特殊字符),否则会出现匹配失败的情况
内容的提问来源于stack exchange,提问作者user17938552
相关产品推荐
相关产品推荐

