使用 Gson 序列化时如何在 Firebase Admin SDK 中应用消息 class 的@Key

How to apply the @Key of the Message class in the Firebase Admin SDK when serializing using Gson

在用Gson序列化messageclass的builder创建的对象时,想获取键名android.

我认为 @Key 应该得到 android,而不是 androidConfig,作为序列化的结果,但事实并非如此。 Objectmapper 和 Gson 也是如此。

我的开发环境是Spring Boot 2.3.12.RELEASE, Firebase ADMIN SDK 8.0.1., Gson 2.8.8

[source]
message = Message.builder()
                    .setNotification(Notification.builder()
                            .setTitle(pushMessageDto.getTitle())
                            .setBody(pushMessageDto.getBody())
                            .setImage(pushMessageDto.getImage())
                            .build())
                    .setAndroidConfig(AndroidConfig.builder()
                            .setTtl(3600 * 1000)
                            .setNotification(AndroidNotification.builder()
                                    .setIcon(ar.getIcon())
                                    .setColor(ar.getColor())
                                    .setClickAction(ar.getClickAction())
                                    .build())
                            .build())
                    .setTopic(pushMessageDto.getTopic())
                    .build();
Gson gson = new Gson();
String m = gson.toJson(message);
[serializing results]
{
   "validate_only":false,
   "message":{
      "notification":{
         "title":"a",
         "body":"b",
         "image":"c"
      },
      "androidConfig":{
         "ttl":"3",
         "notification":{
            "icon":"",
            "color":"#32a852",
            "clickAction":"MainActivity",
         }
      },
      "topic":"weather"
   }
}
[Message class of Firebase Admin SDK]
public class Message {

  @Key("data")
  private final Map<String, String> data;

  @Key("notification")
  private final Notification notification;

  @Key("android")
  private final AndroidConfig androidConfig;

  @Key("webpush")
  private final WebpushConfig webpushConfig;

  @Key("apns")
  private final ApnsConfig apnsConfig;

  @Key("token")
  private final String token;

  @Key("topic")
  private final String topic;

  @Key("condition")
  private final String condition;

  @Key("fcm_options")
  private final FcmOptions fcmOptions;

Gson 默认只支持它的 @SerializedName 注释来指定自定义 JSON 成员名称。

假设您正在使用的 @Key 注释在运行时可用 (@Retention(RUNTIME)),您可以编写自定义 FieldNamingStrategy:

public class KeyFieldNamingStrategy implements FieldNamingStrategy {
    private final FieldNamingStrategy delegate;
    
    public KeyFieldNamingStrategy(FieldNamingStrategy delegate) {
        this.delegate = delegate;
    }

    @Override
    public String translateName(Field f) {
        Key key = f.getAnnotation(Key.class);
        if (key == null) {
            // No annotation, use delegate
            return delegate.translateName(f);
        } else {
            return key.value();
        }
    }
}

然后用GsonBuilder注册:

Gson gson = new GsonBuilder()
    // Uses IDENTITY as delegate, which uses field names as is
    .setFieldNamingStrategy(new KeyFieldNamingStrategy(FieldNamingPolicy.IDENTITY))
    .create();