@@ -31,8 +31,47 @@ import (
31
31
"firebase.google.com/go/internal"
32
32
)
33
33
34
+ const maxMessages = 100
34
35
const multipartBoundary = "__END_OF_PART__"
35
36
37
+ // MulticastMessage represents a message that can be sent to multiple devices via Firebase Cloud
38
+ // Messaging (FCM).
39
+ //
40
+ // It contains payload information as well as the list of device registration tokens to which the
41
+ // message should be sent. A single MulticastMessage may contain up to 100 registration tokens.
42
+ type MulticastMessage struct {
43
+ Tokens []string
44
+ Data map [string ]string
45
+ Notification * Notification
46
+ Android * AndroidConfig
47
+ Webpush * WebpushConfig
48
+ APNS * APNSConfig
49
+ }
50
+
51
+ func (mm * MulticastMessage ) toMessages () ([]* Message , error ) {
52
+ if len (mm .Tokens ) == 0 {
53
+ return nil , errors .New ("tokens must not be nil or empty" )
54
+ }
55
+ if len (mm .Tokens ) > maxMessages {
56
+ return nil , fmt .Errorf ("tokens must not contain more than %d elements" , maxMessages )
57
+ }
58
+
59
+ var messages []* Message
60
+ for _ , token := range mm .Tokens {
61
+ temp := & Message {
62
+ Token : token ,
63
+ Data : mm .Data ,
64
+ Notification : mm .Notification ,
65
+ Android : mm .Android ,
66
+ Webpush : mm .Webpush ,
67
+ APNS : mm .APNS ,
68
+ }
69
+ messages = append (messages , temp )
70
+ }
71
+
72
+ return messages , nil
73
+ }
74
+
36
75
// SendResponse represents the status of an individual message that was sent as part of a batch
37
76
// request.
38
77
type SendResponse struct {
@@ -48,27 +87,87 @@ type BatchResponse struct {
48
87
Responses []* SendResponse
49
88
}
50
89
51
- // SendAll sends all the messages in the given array via Firebase Cloud Messaging.
90
+ // SendAll sends the messages in the given array via Firebase Cloud Messaging.
52
91
//
53
92
// The messages array may contain up to 100 messages. SendAll employs batching to send the entire
54
93
// array of mssages as a single RPC call. Compared to the `Send()` function,
55
- // this is a significantly more efficient way to send multiple messages. The responses
56
- // list obtained from the return value corresponds to the order of input messages. An error from
94
+ // this is a significantly more efficient way to send multiple messages. The responses list
95
+ // obtained from the return value corresponds to the order of the input messages. An error from
57
96
// SendAll indicates a total failure -- i.e. none of the messages in the array could be sent.
58
97
// Partial failures are indicated by a `BatchResponse` return value.
59
98
func (c * Client ) SendAll (ctx context.Context , messages []* Message ) (* BatchResponse , error ) {
60
99
return c .sendBatch (ctx , messages , false )
61
100
}
62
101
102
+ // SendAllDryRun sends the messages in the given array via Firebase Cloud Messaging in the
103
+ // dry run (validation only) mode.
104
+ //
105
+ // This function does not actually deliver any messages to target devices. Instead, it performs all
106
+ // the SDK-level and backend validations on the messages, and emulates the send operation.
107
+ //
108
+ // The messages array may contain up to 100 messages. SendAllDryRun employs batching to send the
109
+ // entire array of mssages as a single RPC call. Compared to the `SendDryRun()` function, this
110
+ // is a significantly more efficient way to validate sending multiple messages. The responses list
111
+ // obtained from the return value corresponds to the order of the input messages. An error from
112
+ // SendAllDryRun indicates a total failure -- i.e. none of the messages in the array could be sent
113
+ // for validation. Partial failures are indicated by a `BatchResponse` return value.
114
+ func (c * Client ) SendAllDryRun (ctx context.Context , messages []* Message ) (* BatchResponse , error ) {
115
+ return c .sendBatch (ctx , messages , true )
116
+ }
117
+
118
+ // SendMulticast sends the given multicast message to all the FCM registration tokens specified.
119
+ //
120
+ // The tokens array in MulticastMessage may contain up to 100 tokens. SendMulticast uses the
121
+ // `SendAll()` function to send the given message to all the target recipients. The
122
+ // responses list obtained from the return value corresponds to the order of the input tokens. An
123
+ // error from SendMulticast indicates a total failure -- i.e. the message could not be sent to any
124
+ // of the recipients. Partial failures are indicated by a `BatchResponse` return value.
125
+ func (c * Client ) SendMulticast (ctx context.Context , message * MulticastMessage ) (* BatchResponse , error ) {
126
+ messages , err := toMessages (message )
127
+ if err != nil {
128
+ return nil , err
129
+ }
130
+
131
+ return c .SendAll (ctx , messages )
132
+ }
133
+
134
+ // SendMulticastDryRun sends the given multicast message to all the specified FCM registration
135
+ // tokens in the dry run (validation only) mode.
136
+ //
137
+ // This function does not actually deliver any messages to target devices. Instead, it performs all
138
+ // the SDK-level and backend validations on the messages, and emulates the send operation.
139
+ //
140
+ // The tokens array in MulticastMessage may contain up to 100 tokens. SendMulticastDryRun uses the
141
+ // `SendAllDryRun()` function to send the given message. The responses list obtained from
142
+ // the return value corresponds to the order of the input tokens. An error from SendMulticastDryRun
143
+ // indicates a total failure -- i.e. none of the messages were sent to FCM for validation. Partial
144
+ // failures are indicated by a `BatchResponse` return value.
145
+ func (c * Client ) SendMulticastDryRun (ctx context.Context , message * MulticastMessage ) (* BatchResponse , error ) {
146
+ messages , err := toMessages (message )
147
+ if err != nil {
148
+ return nil , err
149
+ }
150
+
151
+ return c .SendAllDryRun (ctx , messages )
152
+ }
153
+
154
+ func toMessages (message * MulticastMessage ) ([]* Message , error ) {
155
+ if message == nil {
156
+ return nil , errors .New ("message must not be nil" )
157
+ }
158
+
159
+ return message .toMessages ()
160
+ }
161
+
63
162
func (c * Client ) sendBatch (
64
163
ctx context.Context , messages []* Message , dryRun bool ) (* BatchResponse , error ) {
65
164
66
165
if len (messages ) == 0 {
67
166
return nil , errors .New ("messages must not be nil or empty" )
68
167
}
69
168
70
- if len (messages ) > 100 {
71
- return nil , errors . New ("messages must not contain more than 100 elements" )
169
+ if len (messages ) > maxMessages {
170
+ return nil , fmt . Errorf ("messages must not contain more than %d elements" , maxMessages )
72
171
}
73
172
74
173
request , err := c .newBatchRequest (messages , dryRun )
0 commit comments