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

Getter与Setter失效:无法将Facebook测试用户生日写入Firestore

解决Facebook登录获取生日后UserInfo getter返回空的问题

哎,我之前做Facebook登录集成的时候也碰到过类似的坑!咱们一步步来排查可能的问题:

1. 先确认Facebook权限是否到位

Facebook的birthday字段不是默认就能拿到的,必须申请user_birthday权限。你在发起登录请求的时候,有没有把这个权限加进去?比如:

// 登录请求里要包含user_birthday权限
LoginManager.getInstance().logInWithReadPermissions(
    this, 
    Arrays.asList("public_profile", "user_birthday")
);

如果没加这个权限,GraphRequest返回的JSONObject里根本就没有birthday字段,自然设置到UserInfo里的是空值。

2. 检查UserInfo类的setter/getter是否正确

大概率是这里的小细节出错了!比如字段名和setter里的赋值不匹配,或者getter返回的不是正确的字段。举个正确的UserInfo类示例:

public class UserInfo {
    private String id;
    private String birthday;

    // 空构造(Firestore需要)
    public UserInfo() {}

    public UserInfo(String id, String birthday) {
        this.id = id;
        this.birthday = birthday;
    }

    // 正确的getter和setter
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getBirthday() {
        return birthday;
    }

    public void setBirthday(String birthday) {
        // 一定要确保是给当前实例的birthday字段赋值
        this.birthday = birthday;
    }
}

仔细检查有没有拼写错误,比如字段名是birthDate但setter里写成了this.birthday = birthday,这种笔误很容易踩坑!

3. 警惕异步回调的时机问题

Facebook的GraphRequest是异步执行的!如果你在onStart初始化了UserInfo后,马上就调用userInfo.getBirthday(),这时候GraphRequest还没拿到数据,setter还没执行,自然返回空。

正确的做法是必须在GraphRequest的成功回调里再操作UserInfo,比如:

// 登录成功后发起GraphRequest获取用户信息
GraphRequest request = GraphRequest.newMeRequest(
    AccessToken.getCurrentAccessToken(),
    new GraphRequest.GraphJSONObjectCallback() {
        @Override
        public void onCompleted(JSONObject object, GraphResponse response) {
            try {
                String userId = object.getString("id");
                String userBirthday = object.getString("birthday");
                
                // 在这里给UserInfo赋值
                userInfo.setId(userId);
                userInfo.setBirthday(userBirthday);
                
                // 这里调用getter就能拿到值了!
                Log.d("DEBUG", "生日:" + userInfo.getBirthday());
                
                // 接着写入Firestore
                FirebaseFirestore.getInstance()
                    .collection("users")
                    .document(userId)
                    .set(userInfo)
                    .addOnSuccessListener(aVoid -> Log.d("DEBUG", "写入成功"))
                    .addOnFailureListener(e -> Log.e("DEBUG", "写入失败:" + e.getMessage()));
            } catch (JSONException e) {
                e.printStackTrace();
                Log.e("DEBUG", "解析Facebook数据失败:" + e.getMessage());
            }
        }
    });

Bundle parameters = new Bundle();
// 指定要获取的字段,必须包含birthday
parameters.putString("fields", "id,birthday");
request.setParameters(parameters);
request.executeAsync();

4. 确认UserInfo实例的一致性

别犯低级错误:你是不是在onStart初始化了一个全局的UserInfo实例,但在GraphRequest回调里又new了一个新的?比如:

// 全局变量
private UserInfo userInfo;

@Override
protected void onStart() {
    super.onStart();
    // 初始化全局实例
    userInfo = new UserInfo();
}

// 回调里如果这样写就错了!
public void onCompleted(JSONObject object, GraphResponse response) {
    // 这里new了新的实例,和全局的不是同一个
    UserInfo userInfo = new UserInfo();
    userInfo.setBirthday(...);
}

这种情况下,全局的userInfo根本没被赋值,调用getter当然返回空!一定要确保全程用的是同一个实例。

先从这几点排查,应该能解决问题!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:39:36