All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.firebase.messaging.Message Maven / Gradle / Ivy

/*
 * Copyright 2018 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.firebase.messaging;

import static com.google.common.base.Preconditions.checkArgument;

import com.google.api.client.util.Key;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.primitives.Booleans;
import com.google.firebase.internal.NonNull;
import java.util.HashMap;
import java.util.Map;

/**
 * Represents a message that can be sent via Firebase Cloud Messaging (FCM). Contains payload
 * information as well as the recipient information. The recipient information must contain exactly
 * one token, topic or condition parameter. Instances of this class are thread-safe and immutable.
 * Use {@link Message.Builder} to create new instances.
 *
 * @see
 * FCM message
 * format
 */
public class Message {

  @Key("data")
  private final Map 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;

  private Message(Builder builder) {
    this.data = builder.data.isEmpty() ? null : ImmutableMap.copyOf(builder.data);
    this.notification = builder.notification;
    this.androidConfig = builder.androidConfig;
    this.webpushConfig = builder.webpushConfig;
    this.apnsConfig = builder.apnsConfig;
    int count = Booleans.countTrue(
        !Strings.isNullOrEmpty(builder.token),
        !Strings.isNullOrEmpty(builder.topic),
        !Strings.isNullOrEmpty(builder.condition)
    );
    checkArgument(count == 1, "Exactly one of token, topic or condition must be specified");
    this.token = builder.token;
    this.topic = stripPrefix(builder.topic);
    this.condition = builder.condition;
    this.fcmOptions = builder.fcmOptions;
  }

  @VisibleForTesting
  Map getData() {
    return data;
  }

  @VisibleForTesting
  Notification getNotification() {
    return notification;
  }

  @VisibleForTesting
  AndroidConfig getAndroidConfig() {
    return androidConfig;
  }

  @VisibleForTesting
  WebpushConfig getWebpushConfig() {
    return webpushConfig;
  }

  @VisibleForTesting
  ApnsConfig getApnsConfig() {
    return apnsConfig;
  }

  @VisibleForTesting
  String getToken() {
    return token;
  }

  @VisibleForTesting
  String getTopic() {
    return topic;
  }

  @VisibleForTesting
  String getCondition() {
    return condition;
  }

  @VisibleForTesting
  FcmOptions getFcmOptions() {
    return fcmOptions;
  }

  Map wrapForTransport(boolean dryRun) {
    ImmutableMap.Builder payload = ImmutableMap.builder()
        .put("message", this);
    if (dryRun) {
      payload.put("validate_only", true);
    }
    return payload.build();
  }

  private static String stripPrefix(String topic) {
    if (Strings.isNullOrEmpty(topic)) {
      return null;
    }
    if (topic.startsWith("/topics/")) {
      topic = topic.replaceFirst("^/topics/", "");
    }
    // Checks for illegal characters and empty string.
    checkArgument(topic.matches("[a-zA-Z0-9-_.~%]+"), "Malformed topic name");
    return topic;
  }

  /**
   * Creates a new {@link Message.Builder}.
   *
   * @return A {@link Message.Builder} instance.
   */
  public static Builder builder() {
    return new Builder();
  }

  public static class  Builder {

    private final Map data = new HashMap<>();
    private Notification notification;
    private AndroidConfig androidConfig;
    private WebpushConfig webpushConfig;
    private ApnsConfig apnsConfig;
    private String token;
    private String topic;
    private String condition;
    private FcmOptions fcmOptions;

    private Builder() {}

    /**
     * Sets the notification information to be included in the message.
     *
     * @param notification A {@link Notification} instance.
     * @return This builder.
     */
    public Builder setNotification(Notification notification) {
      this.notification = notification;
      return this;
    }

    /**
     * Sets the Android-specific information to be included in the message.
     *
     * @param androidConfig An {@link AndroidConfig} instance.
     * @return This builder.
     */
    public Builder setAndroidConfig(AndroidConfig androidConfig) {
      this.androidConfig = androidConfig;
      return this;
    }

    /**
     * Sets the Webpush-specific information to be included in the message.
     *
     * @param webpushConfig A {@link WebpushConfig} instance.
     * @return This builder.
     */
    public Builder setWebpushConfig(WebpushConfig webpushConfig) {
      this.webpushConfig = webpushConfig;
      return this;
    }

    /**
     * Sets the information specific to APNS (Apple Push Notification Service).
     *
     * @param apnsConfig An {@link ApnsConfig} instance.
     * @return This builder.
     */
    public Builder setApnsConfig(ApnsConfig apnsConfig) {
      this.apnsConfig = apnsConfig;
      return this;
    }

    /**
     * Sets the registration token of the device to which the message should be sent.
     *
     * @param token A valid device registration token.
     * @return This builder.
     */
    public Builder setToken(String token) {
      this.token = token;
      return this;
    }

    /**
     * Sets the name of the FCM topic to which the message should be sent. Topic names may
     * contain the {@code /topics/} prefix.
     *
     * @param topic A valid topic name.
     * @return This builder.
     */
    public Builder setTopic(String topic) {
      this.topic = topic;
      return this;
    }

    /**
     * Sets the FCM condition to which the message should be sent.
     *
     * @param condition A valid condition string (e.g. {@code "'foo' in topics"}).
     * @return This builder.
     */
    public Builder setCondition(String condition) {
      this.condition = condition;
      return this;
    }

    /**
     * Adds the given key-value pair to the message as a data field. Key or the value may not be
     * null.
     *
     * @param key Name of the data field. Must not be null.
     * @param value Value of the data field. Must not be null.
     * @return This builder.
     */
    public Builder putData(@NonNull String key, @NonNull String value) {
      this.data.put(key, value);
      return this;
    }

    /**
     * Adds all the key-value pairs in the given map to the message as data fields. None of the
     * keys or values may be null.
     *
     * @param map A non-null map of data fields. Map must not contain null keys or values.
     * @return This builder.
     */
    public Builder putAllData(@NonNull Map map) {
      this.data.putAll(map);
      return this;
    }

    /**
     * Sets the {@link FcmOptions}, which can be overridden by the platform-specific {@code
     * fcm_options} fields.
     */
    public Builder setFcmOptions(FcmOptions fcmOptions) {
      this.fcmOptions = fcmOptions;
      return this;
    }

    /**
     * Creates a new {@link Message} instance from the parameters set on this builder.
     *
     * @return A new {@link Message} instance.
     * @throws IllegalArgumentException If any of the parameters set on the builder are invalid.
     */
    public Message build() {
      return new Message(this);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy