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

如何从Firebase AuthUI的Facebook提供商获取额外用户信息

如何从Firebase AuthUI的Facebook提供商获取生日和性别信息

嘿,我懂你现在的困惑——你已经通过AuthUI请求了Facebook的生日和性别权限,但在Firebase User的ProviderData里找不到这些数据,反而调试时发现它们藏在一个叫zzdd的内部属性里。先给你敲个警钟:绝对不要直接用这个zzdd属性!它是Firebase Auth库的内部私有字段,Google随时可能改名字或者删掉它,到时候你的代码直接就崩了。

正确的做法是通过Facebook的Graph API来获取这些数据,毕竟这些信息本来就存储在Facebook那边,步骤很简单:

第一步:获取Facebook访问令牌

先从Firebase用户的提供商数据里提取Facebook的访问令牌:

FirebaseUser mUser = FirebaseAuth.getInstance().getCurrentUser();
String facebookAccessToken = null;

// 遍历提供商数据,定位到Facebook的条目
for (UserInfo userInfo : mUser.getProviderData()) {
    if ("facebook.com".equals(userInfo.getProviderId())) {
        // 方式1:从Firebase用户的IdToken中获取
        mUser.getIdToken(false)
            .addOnSuccessListener(result -> {
                facebookAccessToken = result.getToken();
                // 拿到令牌后调用Graph API获取数据
                fetchFacebookUserData(facebookAccessToken);
            });
        // 方式2:如果集成了Facebook SDK,直接用官方API拿令牌
        // facebookAccessToken = AccessToken.getCurrentAccessToken().getToken();
        break;
    }
}

第二步:调用Facebook Graph API获取目标数据

拿到令牌后,调用/me端点并指定需要的字段(birthday和gender)。这里给你两种常用的实现方式:

方式一:用OkHttp发起请求

如果你习惯用OkHttp,代码可以这么写:

private void fetchFacebookUserData(String token) {
    OkHttpClient client = new OkHttpClient();
    String requestUrl = String.format("https://graph.facebook.com/me?fields=birthday,gender&access_token=%s", token);
    
    Request request = new Request.Builder().url(requestUrl).build();
    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            // 请求失败,处理错误逻辑
            e.printStackTrace();
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            if (response.isSuccessful()) {
                String jsonStr = response.body().string();
                try {
                    JSONObject userData = new JSONObject(jsonStr);
                    String birthday = userData.optString("birthday");
                    String gender = userData.optString("gender");
                    
                    // 注意:这里是子线程,要切回主线程处理UI或数据
                    runOnUiThread(() -> {
                        // 在这里使用你的生日和性别数据
                        Log.d("FacebookUserData", "生日:" + birthday + ",性别:" + gender);
                    });
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }
    });
}

方式二:用Facebook官方SDK的GraphRequest

如果已经集成了Facebook SDK,用GraphRequest会更省心:

private void fetchFacebookUserDataWithSDK() {
    AccessToken accessToken = AccessToken.getCurrentAccessToken();
    if (accessToken != null && !accessToken.isExpired()) {
        GraphRequest request = GraphRequest.newMeRequest(
                accessToken,
                (jsonObject, response) -> {
                    try {
                        String birthday = jsonObject.optString("birthday");
                        String gender = jsonObject.optString("gender");
                        // GraphRequest默认在主线程回调,可直接处理数据
                        Log.d("FacebookUserData", "生日:" + birthday + ",性别:" + gender);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                });

        Bundle params = new Bundle();
        params.putString("fields", "birthday,gender");
        request.setParameters(params);
        request.executeAsync();
    }
}

为什么不能碰zzdd?

再强调一次:zzdd是Firebase Auth库的内部私有字段,完全没有公开的API承诺它会一直存在。Firebase团队在更新版本时,可能随便把它改名为zzde或者调整数据结构,你的代码要么拿不到数据,要么直接抛出反射异常(如果用反射访问的话),这绝对是不稳定的写法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:05:07