【问题标题】:Firebase: Android : How to show list of contacts who have the app InstalledFirebase:Android:如何显示已安装应用程序的联系人列表
【发布时间】:2018-01-05 05:48:09
【问题描述】:

我正在通过 firebase 使用 Google 身份验证,并且正在成功登录用户。我还从电话簿(设备)中检索了联系人列表,并将其显示在我应用程序片段中的列表视图上。但现在我希望在我的联系人中显示用户谁安装了我的应用程序,这样当点击时他们将与他们进行私人聊天,其他联系人在点击时将使他们能够发送应用邀请。简而言之:我想查看在其设备上安装了该应用程序的联系人列表。

【问题讨论】:

  • 请向我们展示您到目前为止所做的尝试以及您面临的问题。
  • 您如何在联系人列表中指明谁安装了应用程序,谁没有安装?即,如果我查看了您的所有联系人,会告诉我某个联系人已安装应用程序?
  • 你解决了吗?我在任何地方都找不到答案。

标签: java android firebase firebase-authentication


【解决方案1】:

我能够通过三个简单的步骤实现这一目标。

  • 获取手机联系人列表
  • 获取 Firestore 上所有电话号码的列表
  • 比较两个列表并返回共同元素。

为了使用我的方法,您需要在 Firestore 上有一个集合,其中包含所有用户的电话号码作为文档,如下图所示:

步骤如下:

第 1 步:我使用 ContentResolver 获得了所有用户联系人的列表。如果您已授予READ_CONTACTS 权限,则可以使用以下方法检索此列表。

public ArrayList<String> getContacts(ContentResolver cr) {

    // list to be returned
    ArrayList<String> numbers = new ArrayList<>();

    // cursor
    Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);

    if ((cur != null ? cur.getCount() : 0) > 0) {

        while (cur != null && cur.moveToNext()) {

            String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
            if (cur.getInt(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0) {

                Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id}, null);
                while (pCur.moveToNext()) {
                    String phoneNo = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                    Log.i(TAG, "Name: " + name);
                    numbers.add(formatRightWay(phoneNo));
                }

                pCur.close();
            }
          }
        }

        if(cur!=null){
            cur.close();
          }

        return numbers;
}

第 2 步:我通过获取 user 集合的文档 ID 获得了 Firestore 上所有电话号码的列表。这是一个快速实现:

firestore.collection("users").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
    if (task.isSuccessful()) {
        List<String> list = new ArrayList<>();
        for (QueryDocumentSnapshot document : task.getResult()) {
            list.add(document.getId());
        }
        // this is the list you need
        Log.d(TAG, list.toString());
    } else {
        Log.d(TAG, "Error getting documents: ", task.getException());
    }
  }
});

第 3 步: 编写一个比较两个列表并返回相似元素的方法。

public static ArrayList<String> shuffleBothLists(ArrayList<String> phoneContacts, List<String> firebaseContacts) {
    ArrayList<String> result = new ArrayList<>();

    for(String s: firebaseContacts) {
        if(phoneContacts.contains(s) && !result.contains(s)) {
            result.add(s);
        }
    }

    return result;
}

上述方法返回的列表是您安装了该应用的联系人。

干杯!

【讨论】:

  • 有些号码的国家/地区代码可能无法与您的 Firebase 用户正确匹配。
  • @LearnToday,在这种情况下,您的项目应该有一个固定的电话号码格式。 在注册时以及在查询时验证并确保用户的电话号码符合您的格式。
【解决方案2】:

首先检索联系人列表..

    'ContentResolver cr = getContext().getContentResolver();
        Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null);
        if (cur.getCount() > 0) {
            while (cur.moveToNext()) {
                String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
                Cursor cur1 = cr.query(
                        ContactsContract.CommonDataKinds.Email.CONTENT_URI, null,
                        ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?",
                        new String[]{id}, null);
                while (cur1.moveToNext()) {
                    //to get the contact names
                    HashMap<String, String> map = new HashMap<>();

                    String name=cur1.getString(cur1.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                    String email = cur1.getString(cur1.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));

                    if( email != null ){
                        map.put("name", name);
                        map.put("email", email);
                        getContactList.add(map);
                    }
                }
                cur1.close();
            }
        }'

在此之后,您可以维护一个可以存储经过身份验证的用户信息的 firebase 数据库表,您可以将您的联系人与您从 firebase 用户数据库中获取的列表同步。

    'mapChat = new HashMap<>();
        Log.d("Debug", clist.toString());
        userReference1 = FirebaseDatabase.getInstance().getReference().child("Users");
        userReference1.keepSynced(true);
        userReference1.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                for (int x = 0; x < clist.size(); x++) {
                    //Log.d("Debug" ,list.get(x).get("email").toString());

                    for (DataSnapshot dsp : dataSnapshot.getChildren()) {

                        if (dsp.hasChild("email")) {

                            //    Log.d("Debug" , "setnewuser "  + dsp.child("email").getValue().toString());
                            if (dsp.child("email").getValue().toString().equals(clist.get(x).get("email").toString())) {
                                Log.d("Debug", "contact updated");
                                String uid = dsp.getKey().toString();
                                reference1 = FirebaseDatabase.getInstance().getReference().child("Users").child(id).child("contacts").child(uid);

                                mapChat.put("name", clist.get(x).get("name"));
                                mapChat.put("email", clist.get(x).get("email"));
                                mapChat.put("chats", "false");
                                reference1.setValue(mapChat);
                            }
                        }
                    }
                }
                reference1.onDisconnect();
                contactIdInterface1.contactUpdated();
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });'

【讨论】:

  • 您建议如何检索 Firebase 身份验证用户列表?你有一些可以提供解决方案的代码示例吗?
  • 我很确定这并不能提供解决方案,因为有些联系人安装了该应用程序而有些则没有 - 没有标志可以指示哪个是哪个。当点击它时,它也没有提供进入私人聊天室的方法。
  • @Jay 这个方法有效,我已经将它用于我的聊天应用程序,当然我们需要在 firebase 中维护聊天数据库,以便可以为列表中的每个联系人提供一个聊天室。
  • 不要误会我的意思,它是工作代码,但它不是问题的解决方案。 OP 想要一个解决方案,在我的联系人中显示安装了我的应用程序的用户。他不想将他的联系人复制到 Firebase,这是解决方案中的代码主要做的事情,他想要一个解决方案来跟踪谁安装了他的应用程序。
【解决方案3】:

在firebase中启用和实现电话号码登录方法,这样您就可以从firebase中检索联系人并将其与本地联系人列表进行比较,这很容易实现您的逻辑

【讨论】:

    【解决方案4】:

    我让你加入意味着你正在使用 firebase。现在,如果您的应用程序安装在您的设备中,您希望将所有联系人上传到 firebase 数据库中的服务器。

    试试下面的代码:

    public class YourActivity extends AppCompatActivity {
    
    ProgressDialog dialog;
    DatabaseReference yourReference;//your database reference
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        yourReference = FirebaseDatabase.getInstance().getReference().child("users");
        setContentView(R.layout.activity_your);
        dialog = new ProgressDialog(this);
        dialog.setMessage("Uploading contacts...");
    
    // Query for contacts through content resolver. You will get a cursor.
        Cursor contacts = getContentResolver().query(
                ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                new String[]{
                        ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
                        ContactsContract.CommonDataKinds.Phone.NUMBER
                },
                null,
                null,
                null
        );
    
    // If you have a list as your data, firebase facilitates you to upload that easily by a single HashMap object. Create a HashMap object.
    
        HashMap<String,Object> map = new HashMap<>();
    
    // Loop contacts cursor with map to put all contacts in map. I used contact name as key and number as its value (simple and pretty way).
        if(contacts!=null) {
            while(contacts.moveToNext()){
                map.put(
                        contacts.getString(contacts.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)),
                        contacts.getString(contacts.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))
                );
            }
            contacts.close();
        }
    
        dialog.show();
    //write map to firebase database reference...
        yourReference.updateChildren(map)
    //this onSuccessListener is optional. You can terminate above line of code by ";" (semicolon).
                .addOnSuccessListener(new OnSuccessListener<Void>() {
                    @Override
                    public void onSuccess(Void aVoid) {
                        dialog.dismiss();
                        Toast.makeText(YourActivity.this, "Contacts uploaded suffessfully!", Toast.LENGTH_SHORT).show();
                    }
                })
    //this onFailureListener is also optional.
        .addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                dialog.dismiss();
                Log.w("MKN","Error: "+e.getMessage());
                Toast.makeText(YourActivity.this, "Contacts upload failed.", Toast.LENGTH_SHORT).show();
            }
        });
    }
    }
    

    您需要提供 READ_CONTACTS 权限才能查询联系人表。 同样在 firebase 规则中,“write”键的值必须为“true”才能写入数据库。

    【讨论】:

      【解决方案5】:

      无法直接列出联系人。您需要在firebase数据库中为用户创建一个节点,以便在注册后存储用户详细信息,然后您可以检索这些用户详细信息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多