Skip to content

Commit 10d776d

Browse files
authored
Merge branch 'master' into user-workflow
2 parents d442127 + 4c053ba commit 10d776d

18 files changed

+1195
-52
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,3 @@ bin/
22
obj/
33
.vscode/
44
.vs/
5-

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Unreleased
22

3+
- [added] Implemented the `SendAllAsync()` and `SendMulticastAsync()` APIs in
4+
the `FirebaseMessaging` class.
5+
6+
# v1.2.1
7+
38
- [fixed] The `VerifyIdTokenAsync()` function now tolerates a clock skew of up
49
to 5 minutes when comparing JWT timestamps.
510

FirebaseAdmin/FirebaseAdmin.IntegrationTests/FirebaseMessagingTest.cs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,76 @@ public async Task Send()
4949
Assert.True(!string.IsNullOrEmpty(id));
5050
Assert.Matches(new Regex("^projects/.*/messages/.*$"), id);
5151
}
52+
53+
[Fact]
54+
public async Task SendAll()
55+
{
56+
var message1 = new Message()
57+
{
58+
Topic = "foo-bar",
59+
Notification = new Notification()
60+
{
61+
Title = "Title",
62+
Body = "Body",
63+
},
64+
Android = new AndroidConfig()
65+
{
66+
Priority = Priority.Normal,
67+
TimeToLive = TimeSpan.FromHours(1),
68+
RestrictedPackageName = "com.google.firebase.testing",
69+
},
70+
};
71+
var message2 = new Message()
72+
{
73+
Topic = "fiz-buz",
74+
Notification = new Notification()
75+
{
76+
Title = "Title",
77+
Body = "Body",
78+
},
79+
Android = new AndroidConfig()
80+
{
81+
Priority = Priority.Normal,
82+
TimeToLive = TimeSpan.FromHours(1),
83+
RestrictedPackageName = "com.google.firebase.testing",
84+
},
85+
};
86+
var response = await FirebaseMessaging.DefaultInstance.SendAllAsync(new[] { message1, message2 }, dryRun: true);
87+
Assert.NotNull(response);
88+
Assert.Equal(2, response.SuccessCount);
89+
Assert.True(!string.IsNullOrEmpty(response.Responses[0].MessageId));
90+
Assert.Matches(new Regex("^projects/.*/messages/.*$"), response.Responses[0].MessageId);
91+
Assert.True(!string.IsNullOrEmpty(response.Responses[1].MessageId));
92+
Assert.Matches(new Regex("^projects/.*/messages/.*$"), response.Responses[1].MessageId);
93+
}
94+
95+
[Fact]
96+
public async Task SendMulticast()
97+
{
98+
var multicastMessage = new MulticastMessage
99+
{
100+
Notification = new Notification()
101+
{
102+
Title = "Title",
103+
Body = "Body",
104+
},
105+
Android = new AndroidConfig()
106+
{
107+
Priority = Priority.Normal,
108+
TimeToLive = TimeSpan.FromHours(1),
109+
RestrictedPackageName = "com.google.firebase.testing",
110+
},
111+
Tokens = new[]
112+
{
113+
"token1",
114+
"token2",
115+
},
116+
};
117+
var response = await FirebaseMessaging.DefaultInstance.SendMulticastAsync(multicastMessage, dryRun: true);
118+
Assert.NotNull(response);
119+
Assert.Equal(2, response.FailureCount);
120+
Assert.NotNull(response.Responses[0].Exception);
121+
Assert.NotNull(response.Responses[1].Exception);
122+
}
52123
}
53124
}

FirebaseAdmin/FirebaseAdmin.Snippets/FirebaseMessagingSnippets.cs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
using System;
1616
using System.Collections.Generic;
17+
using System.Linq;
1718
using System.Threading.Tasks;
1819
using FirebaseAdmin.Messaging;
1920

@@ -117,6 +118,107 @@ internal static async Task SendDryRunAsync()
117118
// [END send_dry_run]
118119
}
119120

121+
internal static async Task SendAllAsync()
122+
{
123+
var registrationToken = "YOUR_REGISTRATION_TOKEN";
124+
// [START send_all]
125+
// Create a list containing up to 100 messages.
126+
var messages = new List<Message>()
127+
{
128+
new Message()
129+
{
130+
Notification = new Notification()
131+
{
132+
Title = "Price drop",
133+
Body = "5% off all electronics",
134+
},
135+
Token = registrationToken,
136+
},
137+
new Message()
138+
{
139+
Notification = new Notification()
140+
{
141+
Title = "Price drop",
142+
Body = "2% off all books",
143+
},
144+
Topic = "readers-club",
145+
},
146+
};
147+
148+
var response = await FirebaseMessaging.DefaultInstance.SendAllAsync(messages);
149+
// See the BatchResponse reference documentation
150+
// for the contents of response.
151+
Console.WriteLine($"{response.SuccessCount} messages were sent successfully");
152+
// [END send_all]
153+
}
154+
155+
internal static async Task SendMulticastAsync()
156+
{
157+
// [START send_multicast]
158+
// Create a list containing up to 100 registration tokens.
159+
// These registration tokens come from the client FCM SDKs.
160+
var registrationTokens = new List<string>()
161+
{
162+
"YOUR_REGISTRATION_TOKEN_1",
163+
// ...
164+
"YOUR_REGISTRATION_TOKEN_n",
165+
};
166+
var message = new MulticastMessage()
167+
{
168+
Tokens = registrationTokens,
169+
Data = new Dictionary<string, string>()
170+
{
171+
{ "score", "850" },
172+
{ "time", "2:45" },
173+
},
174+
};
175+
176+
var response = await FirebaseMessaging.DefaultInstance.SendMulticastAsync(message);
177+
// See the BatchResponse reference documentation
178+
// for the contents of response.
179+
Console.WriteLine($"{response.SuccessCount} messages were sent successfully");
180+
// [END send_multicast]
181+
}
182+
183+
internal static async Task SendMulticastAndHandleErrorsAsync()
184+
{
185+
// [START send_multicast_error]
186+
// These registration tokens come from the client FCM SDKs.
187+
var registrationTokens = new List<string>()
188+
{
189+
"YOUR_REGISTRATION_TOKEN_1",
190+
// ...
191+
"YOUR_REGISTRATION_TOKEN_n",
192+
};
193+
var message = new MulticastMessage()
194+
{
195+
Tokens = registrationTokens,
196+
Data = new Dictionary<string, string>()
197+
{
198+
{ "score", "850" },
199+
{ "time", "2:45" },
200+
},
201+
};
202+
203+
var response = await FirebaseMessaging.DefaultInstance.SendMulticastAsync(message);
204+
if (response.FailureCount > 0)
205+
{
206+
var failedTokens = new List<string>();
207+
for (var i = 0; i < response.Responses.Count; i++)
208+
{
209+
if (!response.Responses[i].IsSuccess)
210+
{
211+
// The order of responses corresponds to the order of the registration tokens.
212+
failedTokens.Add(registrationTokens[i]);
213+
}
214+
}
215+
216+
Console.WriteLine($"List of tokens that caused failures: {failedTokens}");
217+
}
218+
219+
// [END send_multicast_error]
220+
}
221+
120222
internal static Message CreateAndroidMessage()
121223
{
122224
// [START android_message]

FirebaseAdmin/FirebaseAdmin.Tests/FirebaseAppTest.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,17 @@ public void GetOrInitService()
210210
});
211211
}
212212

213+
[Fact]
214+
public void GetSdkVersion()
215+
{
216+
var version = FirebaseApp.GetSdkVersion();
217+
218+
var segments = version.Split(".");
219+
Assert.Equal(3, segments.Length);
220+
int result;
221+
Assert.All(segments, (segment) => int.TryParse(segment, out result));
222+
}
223+
213224
public void Dispose()
214225
{
215226
FirebaseApp.DeleteAll();
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright 2018, Google Inc. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using System;
16+
using System.Collections.Generic;
17+
using System.Linq;
18+
using FirebaseAdmin.Messaging;
19+
using Xunit;
20+
21+
namespace FirebaseAdmin.Tests.Messaging
22+
{
23+
public class BatchResponseTest
24+
{
25+
[Fact]
26+
public void EmptyResponses()
27+
{
28+
var responses = new List<SendResponse>();
29+
30+
var batchResponse = new BatchResponse(responses);
31+
32+
Assert.Equal(0, batchResponse.SuccessCount);
33+
Assert.Equal(0, batchResponse.FailureCount);
34+
Assert.Equal(0, batchResponse.Responses.Count);
35+
}
36+
37+
[Fact]
38+
public void SomeResponse()
39+
{
40+
var responses = new SendResponse[]
41+
{
42+
SendResponse.FromMessageId("message1"),
43+
SendResponse.FromMessageId("message2"),
44+
SendResponse.FromException(
45+
new FirebaseException(
46+
"error-message",
47+
null)),
48+
};
49+
50+
var batchResponse = new BatchResponse(responses);
51+
52+
Assert.Equal(2, batchResponse.SuccessCount);
53+
Assert.Equal(1, batchResponse.FailureCount);
54+
Assert.Equal(3, batchResponse.Responses.Count);
55+
Assert.True(responses.SequenceEqual(batchResponse.Responses));
56+
}
57+
58+
[Fact]
59+
public void ResponsesCannotBeNull()
60+
{
61+
Assert.Throws<ArgumentNullException>(() => new BatchResponse(null));
62+
}
63+
}
64+
}

0 commit comments

Comments
 (0)