@@ -27,6 +27,7 @@ import (
27
27
"mime/multipart"
28
28
"net/http"
29
29
"net/textproto"
30
+ "sync"
30
31
31
32
"firebase.google.com/go/v4/internal"
32
33
)
@@ -80,21 +81,145 @@ type SendResponse struct {
80
81
Error error
81
82
}
82
83
83
- // BatchResponse represents the response from the ` SendAll()` and ` SendMulticast()` APIs.
84
+ // BatchResponse represents the response from the SendAll() and SendMulticast() APIs.
84
85
type BatchResponse struct {
85
86
SuccessCount int
86
87
FailureCount int
87
88
Responses []* SendResponse
88
89
}
89
90
91
+ // SendEach sends the messages in the given array via Firebase Cloud Messaging.
92
+ //
93
+ // The messages array may contain up to 500 messages. Unlike SendAll(), SendEach sends the entire
94
+ // array of messages by making a single HTTP call for each message. The responses list
95
+ // obtained from the return value corresponds to the order of the input messages. An error
96
+ // from SendEach or a BatchResponse with all failures indicates a total failure, meaning that
97
+ // none of the messages in the list could be sent. Partial failures or no failures are only
98
+ // indicated by a BatchResponse return value.
99
+ func (c * fcmClient ) SendEach (ctx context.Context , messages []* Message ) (* BatchResponse , error ) {
100
+ return c .sendEachInBatch (ctx , messages , false )
101
+ }
102
+
103
+ // SendEachDryRun sends the messages in the given array via Firebase Cloud Messaging in the
104
+ // dry run (validation only) mode.
105
+ //
106
+ // This function does not actually deliver any messages to target devices. Instead, it performs all
107
+ // the SDK-level and backend validations on the messages, and emulates the send operation.
108
+ //
109
+ // The messages array may contain up to 500 messages. Unlike SendAllDryRun(), SendEachDryRun sends
110
+ // the entire array of messages by making a single HTTP call for each message. The responses list
111
+ // obtained from the return value corresponds to the order of the input messages. An error
112
+ // from SendEachDryRun or a BatchResponse with all failures indicates a total failure, meaning
113
+ // that none of the messages in the list could be sent. Partial failures or no failures are only
114
+ // indicated by a BatchResponse return value.
115
+ func (c * fcmClient ) SendEachDryRun (ctx context.Context , messages []* Message ) (* BatchResponse , error ) {
116
+ return c .sendEachInBatch (ctx , messages , true )
117
+ }
118
+
119
+ // SendMulticast sends the given multicast message to all the FCM registration tokens specified.
120
+ //
121
+ // The tokens array in MulticastMessage may contain up to 500 tokens. SendMulticast uses the
122
+ // SendEach() function to send the given message to all the target recipients. The
123
+ // responses list obtained from the return value corresponds to the order of the input tokens. An error
124
+ // from SendEachForMulticast or a BatchResponse with all failures indicates a total failure, meaning
125
+ // that none of the messages in the list could be sent. Partial failures or no failures are only
126
+ // indicated by a BatchResponse return value.
127
+ func (c * fcmClient ) SendEachForMulticast (ctx context.Context , message * MulticastMessage ) (* BatchResponse , error ) {
128
+ messages , err := toMessages (message )
129
+ if err != nil {
130
+ return nil , err
131
+ }
132
+
133
+ return c .SendEach (ctx , messages )
134
+ }
135
+
136
+ // SendEachForMulticastDryRun sends the given multicast message to all the specified FCM registration
137
+ // tokens in the dry run (validation only) mode.
138
+ //
139
+ // This function does not actually deliver any messages to target devices. Instead, it performs all
140
+ // the SDK-level and backend validations on the messages, and emulates the send operation.
141
+ //
142
+ // The tokens array in MulticastMessage may contain up to 500 tokens. SendEachForMulticastDryRunn uses the
143
+ // SendEachDryRun() function to send the given message. The responses list obtained from
144
+ // the return value corresponds to the order of the input tokens. An error from SendEachForMulticastDryRun
145
+ // or a BatchResponse with all failures indicates a total failure, meaning that of the messages in the
146
+ // list could be sent. Partial failures or no failures are only
147
+ // indicated by a BatchResponse return value.
148
+ func (c * fcmClient ) SendEachForMulticastDryRun (ctx context.Context , message * MulticastMessage ) (* BatchResponse , error ) {
149
+ messages , err := toMessages (message )
150
+ if err != nil {
151
+ return nil , err
152
+ }
153
+
154
+ return c .SendEachDryRun (ctx , messages )
155
+ }
156
+
157
+ func (c * fcmClient ) sendEachInBatch (ctx context.Context , messages []* Message , dryRun bool ) (* BatchResponse , error ) {
158
+ if len (messages ) == 0 {
159
+ return nil , errors .New ("messages must not be nil or empty" )
160
+ }
161
+
162
+ if len (messages ) > maxMessages {
163
+ return nil , fmt .Errorf ("messages must not contain more than %d elements" , maxMessages )
164
+ }
165
+
166
+ var responses []* SendResponse = make ([]* SendResponse , len (messages ))
167
+ var wg sync.WaitGroup
168
+
169
+ for idx , m := range messages {
170
+ if err := validateMessage (m ); err != nil {
171
+ return nil , fmt .Errorf ("invalid message at index %d: %v" , idx , err )
172
+ }
173
+ wg .Add (1 )
174
+ go func (idx int , m * Message , dryRun bool , responses []* SendResponse ) {
175
+ defer wg .Done ()
176
+ var resp string
177
+ var err error
178
+ if dryRun {
179
+ resp , err = c .SendDryRun (ctx , m )
180
+ } else {
181
+ resp , err = c .Send (ctx , m )
182
+ }
183
+ if err == nil {
184
+ responses [idx ] = & SendResponse {
185
+ Success : true ,
186
+ MessageID : resp ,
187
+ }
188
+ } else {
189
+ responses [idx ] = & SendResponse {
190
+ Success : false ,
191
+ Error : err ,
192
+ }
193
+ }
194
+ }(idx , m , dryRun , responses )
195
+ }
196
+ // Wait for all SendDryRun/Send calls to finish
197
+ wg .Wait ()
198
+
199
+ successCount := 0
200
+ for _ , r := range responses {
201
+ if r .Success {
202
+ successCount ++
203
+ }
204
+ }
205
+
206
+ return & BatchResponse {
207
+ Responses : responses ,
208
+ SuccessCount : successCount ,
209
+ FailureCount : len (responses ) - successCount ,
210
+ }, nil
211
+ }
212
+
90
213
// SendAll sends the messages in the given array via Firebase Cloud Messaging.
91
214
//
92
215
// The messages array may contain up to 500 messages. SendAll employs batching to send the entire
93
- // array of mssages as a single RPC call. Compared to the ` Send()` function,
216
+ // array of messages as a single RPC call. Compared to the Send() function,
94
217
// this is a significantly more efficient way to send multiple messages. The responses list
95
218
// obtained from the return value corresponds to the order of the input messages. An error from
96
- // SendAll indicates a total failure -- i.e. none of the messages in the array could be sent.
97
- // Partial failures are indicated by a `BatchResponse` return value.
219
+ // SendAll indicates a total failure, meaning that none of the messages in the array could be
220
+ // sent. Partial failures are indicated by a BatchResponse return value.
221
+ //
222
+ // Deprecated: Use SendEach instead.
98
223
func (c * fcmClient ) SendAll (ctx context.Context , messages []* Message ) (* BatchResponse , error ) {
99
224
return c .sendBatch (ctx , messages , false )
100
225
}
@@ -106,22 +231,26 @@ func (c *fcmClient) SendAll(ctx context.Context, messages []*Message) (*BatchRes
106
231
// the SDK-level and backend validations on the messages, and emulates the send operation.
107
232
//
108
233
// The messages array may contain up to 500 messages. SendAllDryRun employs batching to send the
109
- // entire array of mssages as a single RPC call. Compared to the ` SendDryRun()` function, this
234
+ // entire array of messages as a single RPC call. Compared to the SendDryRun() function, this
110
235
// is a significantly more efficient way to validate sending multiple messages. The responses list
111
236
// 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.
237
+ // SendAllDryRun indicates a total failure, meaning that none of the messages in the array could
238
+ // be sent for validation. Partial failures are indicated by a BatchResponse return value.
239
+ //
240
+ // Deprecated: Use SendEachDryRun instead.
114
241
func (c * fcmClient ) SendAllDryRun (ctx context.Context , messages []* Message ) (* BatchResponse , error ) {
115
242
return c .sendBatch (ctx , messages , true )
116
243
}
117
244
118
245
// SendMulticast sends the given multicast message to all the FCM registration tokens specified.
119
246
//
120
247
// The tokens array in MulticastMessage may contain up to 500 tokens. SendMulticast uses the
121
- // ` SendAll()` function to send the given message to all the target recipients. The
248
+ // SendAll() function to send the given message to all the target recipients. The
122
249
// 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.
250
+ // error from SendMulticast indicates a total failure, meaning that the message could not be sent
251
+ // to any of the recipients. Partial failures are indicated by a BatchResponse return value.
252
+ //
253
+ // Deprecated: Use SendEachForMulticast instead.
125
254
func (c * fcmClient ) SendMulticast (ctx context.Context , message * MulticastMessage ) (* BatchResponse , error ) {
126
255
messages , err := toMessages (message )
127
256
if err != nil {
@@ -138,10 +267,12 @@ func (c *fcmClient) SendMulticast(ctx context.Context, message *MulticastMessage
138
267
// the SDK-level and backend validations on the messages, and emulates the send operation.
139
268
//
140
269
// The tokens array in MulticastMessage may contain up to 500 tokens. SendMulticastDryRun uses the
141
- // ` SendAllDryRun()` function to send the given message. The responses list obtained from
270
+ // SendAllDryRun() function to send the given message. The responses list obtained from
142
271
// 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.
272
+ // indicates a total failure, meaning that none of the messages were sent to FCM for validation.
273
+ // Partial failures are indicated by a BatchResponse return value.
274
+ //
275
+ // Deprecated: Use SendEachForMulticastDryRun instead.
145
276
func (c * fcmClient ) SendMulticastDryRun (ctx context.Context , message * MulticastMessage ) (* BatchResponse , error ) {
146
277
messages , err := toMessages (message )
147
278
if err != nil {
0 commit comments