Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
PushNotificationConfiguration.cs
1using System;
3using System.IO;
4using System.Text;
5using System.Threading.Tasks;
6using Waher.Content;
10using Waher.Events;
21using Waher.Script;
23
25{
31 {
32 private static PushNotificationConfiguration instance = null;
33 private static FirebaseClient firebaseClient = null;
34
35 private string firebaseServiceAccountJson = string.Empty;
36 private string firebaseApiKey = string.Empty;
37 private string firebaseAuthDomain = string.Empty;
38 private string firebaseProjectId = string.Empty;
39 private string firebaseStorageBucket = string.Empty;
40 private string firebaseMessagingSenderId = string.Empty;
41 private string firebaseAppId = string.Empty;
42 private string firebaseWebPushPublicKey = string.Empty;
43
44 private DateTime firebaseServiceAccountJsonUploaded = DateTime.MinValue;
45 private bool useFirebase = false;
46
47 private HttpResource firebaseWebPushJavascript = null;
48 private HttpResource testFirebaseConnection = null;
49 private HttpResource testFirebaseNotification = null;
50
54 [DefaultValueStringEmpty]
56 {
57 get => this.firebaseServiceAccountJson;
58 set => this.firebaseServiceAccountJson = value;
59 }
60
64 [DefaultValueStringEmpty]
65 public string FirebaseApiKey
66 {
67 get => this.firebaseApiKey;
68 set => this.firebaseApiKey = value;
69 }
70
74 [DefaultValueStringEmpty]
75 public string FirebaseAuthDomain
76 {
77 get => this.firebaseAuthDomain;
78 set => this.firebaseAuthDomain = value;
79 }
80
84 [DefaultValueStringEmpty]
85 public string FirebaseProjectId
86 {
87 get => this.firebaseProjectId;
88 set => this.firebaseProjectId = value;
89 }
90
94 [DefaultValueStringEmpty]
96 {
97 get => this.firebaseStorageBucket;
98 set => this.firebaseStorageBucket = value;
99 }
100
104 [DefaultValueStringEmpty]
106 {
107 get => this.firebaseMessagingSenderId;
108 set => this.firebaseMessagingSenderId = value;
109 }
110
114 [DefaultValueStringEmpty]
115 public string FirebaseAppId
116 {
117 get => this.firebaseAppId;
118 set => this.firebaseAppId = value;
119 }
120
125 {
126 get => this.firebaseWebPushPublicKey;
127 set => this.firebaseWebPushPublicKey = value;
128 }
129
133 [DefaultValueDateTimeMinValue]
135 {
136 get => this.firebaseServiceAccountJsonUploaded;
137 set => this.firebaseServiceAccountJsonUploaded = value;
138 }
139
143 [DefaultValue(false)]
144 public bool UseFirebase
145 {
146 get => this.useFirebase;
147 set => this.useFirebase = value;
148 }
149
153 public static FirebaseClient FirebaseClient => firebaseClient;
154
158 public static PushNotificationConfiguration Instance => instance;
159
163 public override string Resource => "/Settings/PushNotification.md";
164
168 public override int Priority => 460;
169
175 public override Task<string> Title(Language Language)
176 {
177 return Language.GetStringAsync(typeof(XmppServerModule), 41, "Push Notification");
178 }
179
183 public override async Task ConfigureSystem()
184 {
185 firebaseClient?.Dispose();
186 firebaseClient = null;
187
188 if (this.useFirebase && !string.IsNullOrEmpty(this.firebaseServiceAccountJson))
189 firebaseClient = await GetClient(this.firebaseServiceAccountJson);
190 }
191
192 private static async Task<FirebaseClient> GetClient(string ServiceAccountJson)
193 {
195 {
196 ISniffer Sniffer = new XmlFileSniffer(Gateway.AppDataFolder + "Firebase" + Path.DirectorySeparatorChar +
197 "Firebase Log %YEAR%-%MONTH%-%DAY%T%HOUR%.xml",
198 Gateway.AppDataFolder + "Transforms" + Path.DirectorySeparatorChar + "SnifferXmlToHtml.xslt",
199 7, BinaryPresentationMethod.ByteCount);
200
201 return await FirebaseClient.CreateAsync(ServiceAccountJson, false, Sniffer);
202 }
203 else
204 return await FirebaseClient.CreateAsync(ServiceAccountJson, false);
205 }
206
211 public override void SetStaticInstance(ISystemConfiguration Configuration)
212 {
213 instance = Configuration as PushNotificationConfiguration;
214 }
215
220 public override Task InitSetup(HttpServer WebServer)
221 {
222 this.firebaseWebPushJavascript = WebServer.Register("/Settings/FirebaseWebPush.js",
223 this.FirebaseWebPushJs, true, false, false);
224 this.testFirebaseConnection = WebServer.Register("/Settings/TestFirebaseConnection",
225 null, this.TestFirebaseConnection, true, false, true);
226 this.testFirebaseNotification = WebServer.Register("/Settings/TestFirebaseNotification",
227 null, this.TestFirebaseNotification, true, false, true);
228
229 return base.InitSetup(WebServer);
230 }
231
236 public override Task UnregisterSetup(HttpServer WebServer)
237 {
238 WebServer.Unregister(this.testFirebaseConnection);
239 WebServer.Unregister(this.testFirebaseNotification);
240
241 return base.UnregisterSetup(WebServer);
242 }
243
247 protected override string ConfigPrivilege => "Admin.Communication.PushNotification";
248
249 private async Task FirebaseWebPushJs(HttpRequest Request, HttpResponse Response)
250 {
251 Response.StatusCode = 200;
252 Response.StatusMessage = "OK";
253 Response.ContentType = JavaScriptCodec.DefaultContentType;
254
255 StringBuilder sb = new StringBuilder();
256
257 sb.AppendLine("import { initializeApp } from 'https://www.gstatic.com/firebasejs/10.12.4/firebase-app.js';");
258 sb.AppendLine("import { getMessaging, getToken } from 'https://www.gstatic.com/firebasejs/10.12.4/firebase-messaging.js';");
259 sb.AppendLine();
260 sb.AppendLine("const firebaseConfig =");
261 sb.AppendLine("{");
262 sb.Append("\tapiKey: '");
263 sb.Append(this.firebaseApiKey);
264 sb.AppendLine("',");
265 sb.Append("\tauthDomain: '");
266 sb.Append(this.firebaseAuthDomain);
267 sb.AppendLine("',");
268 sb.Append("\tprojectId: '");
269 sb.Append(this.firebaseProjectId);
270 sb.AppendLine("',");
271 sb.Append("\tstorageBucket: '");
272 sb.Append(this.firebaseStorageBucket);
273 sb.AppendLine("',");
274 sb.Append("\tmessagingSenderId: '");
275 sb.Append(this.firebaseMessagingSenderId);
276 sb.AppendLine("',");
277 sb.Append("\tappId: '");
278 sb.Append(this.firebaseAppId);
279 sb.AppendLine("'");
280 sb.AppendLine("};");
281 sb.AppendLine();
282 sb.AppendLine("const app = initializeApp(firebaseConfig);");
283 sb.AppendLine("const messaging = getMessaging(app);");
284 sb.AppendLine();
285 sb.AppendLine("window.GetFirebaseToken = function GetFirebaseToken()");
286 sb.AppendLine("{");
287 sb.AppendLine("\tgetToken(messaging, { vapidKey: '" + this.firebaseWebPushPublicKey + "'}).then(");
288 sb.AppendLine("\t\t(token) =>");
289 sb.AppendLine("\t\t{");
290 sb.AppendLine("\t\t\tif (token)");
291 sb.AppendLine("\t\t\t\tFirebaseTokenReceived(token);");
292 sb.AppendLine("\t\t\telse");
293 sb.AppendLine("\t\t\t\tFirebaseTokenRejected();");
294 sb.AppendLine("\t\t}).catch((error) => FirebaseTokenFailure(error));");
295 sb.AppendLine("};");
296
297 await Response.Write(sb.ToString());
298 }
299
300 private async Task TestFirebaseConnection(HttpRequest Request, HttpResponse Response)
301 {
302 Gateway.AssertUserAuthenticated(Request, this.ConfigPrivilege);
303
304 if (!Request.HasData)
305 {
306 await Response.SendResponse(new BadRequestException());
307 return;
308 }
309
310 ContentResponse Content = await Request.DecodeDataAsync();
311 if (Content.HasError ||
312 !(Content.Decoded is Dictionary<string, object> Form) ||
313 !Form.TryGetValue("useFirebase", out object Obj) || !(Obj is bool UseFirebase))
314 {
315 await Response.SendResponse(new BadRequestException());
316 return;
317 }
318
319 if (!Form.TryGetValue("firebaseWebConfig", out Obj) ||
320 !(Obj is string FirebaseWebConfigJson) ||
321 string.IsNullOrEmpty(FirebaseWebConfigJson))
322 {
323 FirebaseWebConfigJson = null;
324 }
325
326 if (!Form.TryGetValue("firebaseWebPushPublicKey", out Obj) ||
327 !(Obj is string FirebaseWebPushPublicKey))
328 {
329 await Response.SendResponse(new BadRequestException());
330 return;
331 }
332
333 this.firebaseWebPushPublicKey = FirebaseWebPushPublicKey;
334
335 if (!Form.TryGetValue("serviceAccountJson", out Obj) ||
336 !(Obj is string ServiceAccountJson) ||
337 string.IsNullOrEmpty(ServiceAccountJson))
338 {
339 ServiceAccountJson = this.firebaseServiceAccountJson;
340 }
341
342 if (Form.TryGetValue("firebaseMessagingSwJsContents", out Obj) &&
343 Obj is string FirebaseMessagingSwJsContents)
344 {
345 await DomainSettings.SetSettingAsync(Request, Path.Combine(Gateway.RootFolder, "firebase-messaging-sw.js"),
346 FirebaseMessagingSwJsContents);
347 }
348
349 string TabID = Request.Header["X-TabID"];
350 if (string.IsNullOrEmpty(TabID))
351 {
352 await Response.SendResponse(new BadRequestException());
353 return;
354 }
355
356 bool Ok = await this.Test(UseFirebase, FirebaseWebConfigJson, ServiceAccountJson, TabID);
357
358 string TimestampHtml = await MarkdownToHtml.ToHtml("JSON file uploaded: **{{Config.FirebaseServiceAccountJsonUploaded}}**.",
359 new Variables()
360 {
361 { "Config", this }
362 });
363
364 Response.StatusCode = 200;
365 Response.StatusMessage = "OK";
366 await Response.Return(new Dictionary<string, object>()
367 {
368 { "ok", Ok },
369 { "timestampHtml", TimestampHtml }
370 });
371 }
372
373 private async Task<bool> Test(bool UseFirebase, string FirebaseWebConfigJson, string ServiceAccountJson, params string[] TabIDs)
374 {
375 try
376 {
377 this.useFirebase = UseFirebase;
378
379 if (this.firebaseServiceAccountJson != ServiceAccountJson)
380 {
381 this.firebaseServiceAccountJson = ServiceAccountJson;
382 this.firebaseServiceAccountJsonUploaded = DateTime.Now;
383 }
384
385 if (!string.IsNullOrEmpty(FirebaseWebConfigJson))
386 {
387 if (!(JSON.Parse(FirebaseWebConfigJson) is Dictionary<string, object> FirebaseWebConfig))
388 throw new Exception("Invalid Web Configuration JSON object.");
389
390 foreach (KeyValuePair<string, object> P in FirebaseWebConfig)
391 {
392 if (!(P.Value is string Value))
393 throw new Exception("Web Configuration object values must be strings.");
394
395 switch (P.Key)
396 {
397 case "apiKey":
398 this.firebaseApiKey = Value;
399 break;
400
401 case "authDomain":
402 this.firebaseAuthDomain = Value;
403 break;
404
405 case "projectId":
406 this.firebaseProjectId = Value;
407 break;
408
409 case "storageBucket":
410 this.firebaseStorageBucket = Value;
411 break;
412
413 case "messagingSenderId":
414 this.firebaseMessagingSenderId = Value;
415 break;
416
417 case "appId":
418 this.firebaseAppId = Value;
419 break;
420
421 default:
422 throw new Exception("Unrecognized property: " + P.Key);
423 }
424 }
425 }
426
427 await Database.Update(this);
428
429 if (UseFirebase)
430 {
431 FirebaseClient Client = null;
432
433 try
434 {
435 Client = await GetClient(ServiceAccountJson);
436
437 if (Client.ProjectId != this.firebaseProjectId)
438 throw new Exception("Inconsistency between mobile phone and web Project IDs");
439
440 await ClientEvents.PushEvent(TabIDs, "ConnectionSuccessful", string.Empty, false, "User");
441
442 firebaseClient?.Dispose();
443 firebaseClient = Client;
444 Client = null;
445
446 return true;
447 }
448 finally
449 {
450 Client?.Dispose();
451 }
452 }
453 else
454 {
455 firebaseClient?.Dispose();
456 firebaseClient = null;
457 }
458 }
459 catch (Exception ex)
460 {
461 Log.Exception(ex);
462 await ClientEvents.PushEvent(TabIDs, "ConnectionError", string.Empty, false, "User");
463 await ClientEvents.PushEvent(TabIDs, "ShowStatus", ex.Message, false, "User");
464 }
465
466 return false;
467 }
468
469 private async Task TestFirebaseNotification(HttpRequest Request, HttpResponse Response)
470 {
471 Gateway.AssertUserAuthenticated(Request, this.ConfigPrivilege);
472
473 if (!Request.HasData)
474 {
475 await Response.SendResponse(new BadRequestException());
476 return;
477 }
478
479 ContentResponse Content = await Request.DecodeDataAsync();
480 if (Content.HasError ||
481 !(Content.Decoded is Dictionary<string, object> Form) ||
482 !Form.TryGetValue("token", out object Obj) || !(Obj is string Token) ||
483 !Form.TryGetValue("title", out Obj) || !(Obj is string Title) ||
484 !Form.TryGetValue("body", out Obj) || !(Obj is string Body))
485 {
486 await Response.SendResponse(new BadRequestException());
487 return;
488 }
489
490 using FirebaseClient Client = await GetClient(this.firebaseServiceAccountJson);
491 NotificationResponse FirebaseResponse = await Client.SendNotification(Token, new NotificationMessage()
492 {
493 Title = Title,
494 Body = Body
495 });
496
497 Response.StatusCode = 200;
498 Response.StatusMessage = "OK";
499 Response.ContentType = JsonCodec.DefaultContentType;
500
501 await Response.Write(JSON.Encode(new Dictionary<string, object>()
502 {
503 { "ok", FirebaseResponse.Ok },
504 { "errorMessage", FirebaseResponse.ErrorMessage }
505 }, false));
506 }
507
512 public override Task<bool> SimplifiedConfiguration()
513 {
514 return Task.FromResult(true);
515 }
516
522 internal static async void PushNotification(PushNotificationToken Token, object Content, PushNotificationRule Rule)
523 {
524 try
525 {
526 switch (Token.Service)
527 {
528 case PushMessagingService.Firebase:
530
532 {
533 StringBuilder sb = new StringBuilder();
534 sb.AppendLine("Push notification payload could not be parsed.");
535 sb.AppendLine();
536 sb.AppendLine("Pattern-Matching Script");
537 sb.AppendLine("--------------------------");
538 sb.AppendLine();
539 sb.AppendLine("```");
540 sb.AppendLine(Rule.PatternMatchingScript);
541 sb.AppendLine("```");
542 sb.AppendLine();
543 sb.AppendLine("Content Script");
544 sb.AppendLine("-----------");
545 sb.AppendLine();
546 sb.AppendLine("```");
547 sb.AppendLine(Rule.ContentScript);
548 sb.AppendLine("```");
549
550 Log.Error(sb.ToString(),
551 new KeyValuePair<string, object>("BareJid", Rule.BareJid.Value),
552 new KeyValuePair<string, object>("MessageType", Rule.MessageType),
553 new KeyValuePair<string, object>("Namespace", Rule.Namespace),
554 new KeyValuePair<string, object>("LocalName", Rule.LocalName),
555 new KeyValuePair<string, object>("Channel", Rule.Channel),
556 new KeyValuePair<string, object>("MessageVariable", Rule.MessageVariable),
557 new KeyValuePair<string, object>("Service", Token.Service),
558 new KeyValuePair<string, object>("ClientType", Token.ClientType),
559 new KeyValuePair<string, object>("Token", Token.Token));
560 return;
561 }
562
563 Builder.ApplyPayload(Payload);
564
565 FirebaseClient Client = firebaseClient;
566 if (!(Client is null))
567 {
568 (NotificationMessage Message, NotificationOptions Options, Dictionary<string, object> Data) = Builder.Build();
569 await Client.SendNotification(Token.Token, Message, Options, Data);
570 }
571 break;
572
573 default:
574 Log.Error("Unsupported push notification service: " + Token.Service);
575 break;
576 }
577 }
578 catch (Exception ex)
579 {
580 Log.Exception(ex);
581 }
582 }
583
587 public const string BROKER_FIREBASE_USE = nameof(BROKER_FIREBASE_USE);
588
592 public const string BROKER_FIREBASE_SERVICE_JSON = nameof(BROKER_FIREBASE_SERVICE_JSON);
593
597 public const string BROKER_FIREBASE_API_KEY = nameof(BROKER_FIREBASE_API_KEY);
598
602 public const string BROKER_FIREBASE_AUTH_DOMAIN = nameof(BROKER_FIREBASE_AUTH_DOMAIN);
603
607 public const string BROKER_FIREBASE_PROJECT_ID = nameof(BROKER_FIREBASE_PROJECT_ID);
608
612 public const string BROKER_FIREBASE_STORAGE_BUCKET = nameof(BROKER_FIREBASE_STORAGE_BUCKET);
613
617 public const string BROKER_FIREBASE_MESSAGING_SENDER_ID = nameof(BROKER_FIREBASE_MESSAGING_SENDER_ID);
618
622 public const string BROKER_FIREBASE_APP_ID = nameof(BROKER_FIREBASE_APP_ID);
623
628 public override async Task<bool> EnvironmentConfiguration()
629 {
630 if (!this.TryGetEnvironmentVariable(BROKER_FIREBASE_USE, false, out this.useFirebase))
631 return false;
632
633 if (!this.useFirebase)
634 return true;
635
636 if (!this.TryGetEnvironmentVariable(BROKER_FIREBASE_SERVICE_JSON, true, out string FileName) ||
637 !File.Exists(FileName))
638 {
639 return false;
640 }
641
642 try
643 {
644 string Json = await Files.ReadAllTextAsync(FileName);
645 FirebaseClient Client = await GetClient(Json);
646
647 this.firebaseServiceAccountJson = Json;
648 this.firebaseServiceAccountJsonUploaded = DateTime.Now;
649
650 if (!this.TryGetEnvironmentVariable(BROKER_FIREBASE_API_KEY, true, out this.firebaseApiKey) ||
651 !this.TryGetEnvironmentVariable(BROKER_FIREBASE_AUTH_DOMAIN, true, out this.firebaseAuthDomain) ||
652 !this.TryGetEnvironmentVariable(BROKER_FIREBASE_PROJECT_ID, true, out this.firebaseProjectId) ||
653 !this.TryGetEnvironmentVariable(BROKER_FIREBASE_STORAGE_BUCKET, true, out this.firebaseStorageBucket) ||
654 !this.TryGetEnvironmentVariable(BROKER_FIREBASE_MESSAGING_SENDER_ID, true, out this.firebaseMessagingSenderId) ||
655 !this.TryGetEnvironmentVariable(BROKER_FIREBASE_APP_ID, true, out this.firebaseAppId))
656 {
657 return false;
658 }
659
660 return Client.ProjectId == this.firebaseProjectId;
661 }
662 catch (Exception ex)
663 {
664 Log.Exception(ex, FileName);
665 return false;
666 }
667 }
668
669}
670 }
Contains information about a response to a content request.
bool HasError
If an error occurred.
object Decoded
Decoded object.
const string DefaultContentType
application/javascript
Helps with common JSON-related tasks.
Definition: JSON.cs:16
static object Parse(string Json)
Parses a JSON string.
Definition: JSON.cs:45
static string Encode(string s)
Encodes a string for inclusion in JSON.
Definition: JSON.cs:537
const string DefaultContentType
application/json
Definition: JsonCodec.cs:20
static Task< string > ToHtml(string Markdown)
Converts a Markdown snippet to a HTML snippet.
Static class managing the application event log. Applications and services log events on this static ...
Definition: Log.cs:14
static void Exception(Exception Exception, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, params KeyValuePair< string, object >[] Tags)
Logs an exception. Event type will be determined by the severity of the exception.
Definition: Log.cs:1657
static void Error(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs an error event.
Definition: Log.cs:692
The ClientEvents class allows applications to push information asynchronously to web clients connecte...
Definition: ClientEvents.cs:51
static Task< int > PushEvent(string[] TabIDs, string Type, object Data)
Puses an event to a set of Tabs, given their Tab IDs.
static Task< bool > SetSettingAsync(IHostReference HostRef, string Key, string Value)
Sets a setting that may vary depending on domain.
Static class managing the runtime environment of the IoT Gateway.
Definition: Gateway.cs:147
static IUser AssertUserAuthenticated(HttpRequest Request, string Privilege)
Makes sure a request is being made from a session with a successful user login.
Definition: Gateway.cs:3868
static string AppDataFolder
Application data folder.
Definition: Gateway.cs:3132
static string RootFolder
Web root folder.
Definition: Gateway.cs:3142
Abstract base class for multi-step system configurations.
static XmppConfiguration Instance
Current instance of configuration.
bool Sniffer
If communication should be sniffed.
The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repe...
static async Task< FirebaseClient > CreateAsync(string GoogleServiceAccountJson, bool Test, params ISniffer[] Sniffers)
Creates an HTTP-based Firebase client.
Task< NotificationResponse > SendNotification(string To, NotificationMessage Message)
Sends a push notification
string ProjectId
Project ID, as from Service Account JSON.
Builds Firebase Cloud Messaging notifications with platform-specific validation
NotificationBuilder ApplyPayload(PushNotificationPayload Payload)
Apply a transport-agnostic push payload to the underlying message/options/data.
Firebase response to sending a notification message.
Represents an HTTP request.
Definition: HttpRequest.cs:22
HttpRequestHeader Header
Request header.
Definition: HttpRequest.cs:182
bool HasData
If the request has data.
Definition: HttpRequest.cs:113
async Task< ContentResponse > DecodeDataAsync()
Decodes data sent in request.
Definition: HttpRequest.cs:139
Base class for all HTTP resources.
Definition: HttpResource.cs:23
Represets a response of an HTTP client request.
Definition: HttpResponse.cs:23
async Task SendResponse()
Sends the response back to the client. If the resource is synchronous, there's no need to call this m...
Task Write(byte[] Data)
Returns binary data in the response.
Task Return(Exception ex)
Returns an error to the client.
Implements an HTTP server.
Definition: HttpServer.cs:41
HttpResource Register(HttpResource Resource)
Registers a resource with the server.
Definition: HttpServer.cs:1568
bool Unregister(HttpResource Resource)
Unregisters a resource from the server.
Definition: HttpServer.cs:1743
Outputs sniffed data to an XML file.
Transport-agnostic push notification payload describing notification intent.
static bool TryParse(object Content, out PushNotificationPayload Payload)
Attempts to parse a payload from a script or serialized object.
string Namespace
Namespace of XML content element in message
string PatternMatchingScript
Pattern-matching script used to extract information from the message being forwarded.
string ContentScript
Content-building script to use when building content to include in notification message.
string MessageVariable
Variable to put the Message XML in, before pattern matching or content script is executed.
string LocalName
Local Name of XML content element in message
PushMessagingService Service
Service used for push notification
string Value
String-representation of the case-insensitive string. (Representation is case sensitive....
Static interface for database persistence. In order to work, a database provider has to be assigned t...
Definition: Database.cs:21
static async Task Update(object Object)
Updates an object in the database.
Definition: Database.cs:1211
Contains static methods
Definition: Files.cs:14
static async Task< string > ReadAllTextAsync(string FileName)
Reads a text file asynchronously.
Definition: Files.cs:84
Contains information about a language.
Definition: Language.cs:17
Task< string > GetStringAsync(Type Type, int Id, string Default)
Gets the string value of a string ID. If no such string exists, a string is created with the default ...
Definition: Language.cs:209
Collection of variables.
Definition: Variables.cs:25
Provides the user configuration options regarding use of Push Notification to reach offline clients.
override void SetStaticInstance(ISystemConfiguration Configuration)
Sets the static instance of the configuration.
string FirebaseAuthDomain
Firebase Authentication Domain (Web Push)
override string ConfigPrivilege
Minimum required privilege for a user to be allowed to change the configuration defined by the class.
override async Task< bool > EnvironmentConfiguration()
Environment configuration by configuring values available in environment variables.
override Task< bool > SimplifiedConfiguration()
Simplified configuration by configuring simple default values.
string FirebaseWebPushPublicKey
Firebase public Web Push (VAPID) key.
override int Priority
Priority of the setting. Configurations are sorted in ascending order.
static PushNotificationConfiguration Instance
Current instance of configuration.
override Task< string > Title(Language Language)
Gets a title for the system configuration.
override async Task ConfigureSystem()
Is called during startup to configure the system.
bool UseFirebase
If Firebase is to be used to push notifications to offline clients.
override Task InitSetup(HttpServer WebServer)
Initializes the setup object.
string FirebaseMessagingSenderId
Firebase Messaging Sender ID (Web Push)
override Task UnregisterSetup(HttpServer WebServer)
Unregisters the setup object.
DateTime FirebaseServiceAccountJsonUploaded
When Firebase Service Account JSON was uploaded
Service Module hosting the XMPP broker and its components.
Interface for system configurations. The gateway will scan all module for system configuration classe...
Interface for sniffers. Sniffers can be added to ICommunicationLayer classes to eavesdrop on communic...
Definition: ISniffer.cs:10
BinaryPresentationMethod
How binary data is to be presented.