com.guru.unity.sdk.core/Runtime/GuruCore/Runtime/Analytics/Analytics.TemplateDefine.cs

754 lines
26 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

namespace Guru
{
using System;
using System.Collections.Generic;
using Facebook.Unity;
using UnityEngine;
//游戏通用模版打点定义
public static partial class Analytics
{
#region 游戏通用打点
/// <summary>
/// 当玩家在游戏中升级时触发
/// </summary>
/// <param name="level">level 等级从1开始 标准点</param>
/// <param name="character">升级的角色,如果没有可不选</param>
/// <param name="extra"></param>
public static void LevelUp(int level, string character, Dictionary<string, object> extra = null)
{
var dict = new Dictionary<string, object>()
{
{ ParameterLevel, level },
{ ParameterCharacter, character }
};
if (extra != null) dict.AddRange(extra, isOverride:true);
LogEvent(EventLevelUp, dict);
}
/// <summary>
/// 玩家已完成解锁成就时触发。
/// </summary>
/// <param name="achievementID">这里的成就ID值项目方自行定义</param>
public static void UnlockAchievement(string achievementID, Dictionary<string, object> extra = null)
{
var dict = new Dictionary<string, object>()
{
{ ParameterAchievementId, achievementID },
};
if (extra != null) dict.AddRange(extra, isOverride:true);
LogEvent(EventUnlockAchievement, dict);
}
/// <summary>
/// 玩家已开始挑战某个关卡时触发。
/// </summary>
/// <param name="levelName">关卡名称</param>
/// <param name="level">关卡数</param>
[Obsolete("Obsolete method, please use <LogLevelStart> instead. will be discard in next version.")]
public static void LevelStart(int level)
{
LogEvent(EventLevelStart, new Dictionary<string, object>()
{
{ ParameterLevel, level },
{ ParameterItemCategory, "main" },
});
}
/// <summary>
/// 玩家已开始挑战某个关卡时触发。
/// </summary>
/// <param name="level">关卡数</param>
/// <param name="levelName">关卡名称</param>
/// <param name="levelType">关卡类型</param>
/// <param name="levelConfigId">关卡配置表 ID</param>
/// <param name="startType">启动方式</param>
/// <param name="isReplay">是否是重玩</param>
/// <param name="extra">额外数据</param>
public static void LogLevelStart(int level, string levelName,
string levelType = "main", string levelConfigId = "", string startType = "play", bool isReplay = false,
Dictionary<string, object> extra = null)
{
Dictionary<string, object> dataDict = new Dictionary<string, object>()
{
{ ParameterLevel, level },
{ ParameterLevelName, levelName },
{ ParameterItemCategory, levelType },
{ ParameterItemId, levelConfigId },
{ ParameterStartType, startType },
{ ParameterReplay, isReplay ? "true" : "false" },
};
if (extra != null)
{
dataDict.AddRange(extra, isOverride:true);
}
LogEvent(EventLevelStart, dataDict);
}
/// <summary>
/// 玩家已开始挑战某个关卡时触发。
/// </summary>
/// <param name="itemCategory">关卡类型(主关卡xx模式/每日挑战/活动1/活动2 等)</param>
/// <param name="itemID">棋局id /图片id</param>
/// <param name="levelName">关卡名称</param>
/// <param name="level">关卡数</param>
[Obsolete("Obsolete method, please use <LogLevelStart> instead. will be discard in next version.")]
internal static void LevelStart(string itemCategory, string itemID, string levelName, int level, bool isReplay, bool isContinue)
{
string startType = "play";
if (isReplay) startType = "replay";
if (isContinue) startType = "continue";
LogEvent(EventLevelStart, new Dictionary<string, object>()
{
{ ParameterItemCategory, itemCategory},
{ ParameterItemId, itemID},
{ ParameterLevelName, levelName },
{ ParameterLevel, level },
{ ParameterReplay, isReplay ? "true" : "false"},
{ ParameterContinue, isContinue ? "true" : "false"},
{ ParameterStartType, startType },
});
}
/// <summary>
/// 关卡结束(Firebase标准事件)
/// </summary>
/// <param name="itemCategory">关卡类型(主关卡xx模式/每日挑战/活动1/活动2 等)</param>
/// <param name="itemID">棋局id /图片id</param>
/// <param name="levelName">关卡名称</param>
/// <param name="level">关卡数</param>
/// <param name="result">"此参数是对success参数的补充说明,除成功/失败/超时/退出这四种情况外,其余情况可自行定义值"</param>
/// <param name="duration">游戏时长单位msec【可选】</param>
/// <param name="step">游戏步数【可选】</param>
/// <param name="score">游戏分数【可选】</param>
/// <param name="isReplay">重玩标记【可选】</param>
[Obsolete("Obsolete method, please use <LogLevelEnd> instead. will be discard in next version.")]
internal static void LevelEnd(string itemCategory, string itemID, string levelName, int level,
ELevelResult result, int? duration = null, int? step = null, int? score = null, bool isReplay = false,
Dictionary<string, object> extra = null)
{
var dict = new Dictionary<string, object>()
{
{ ParameterItemCategory, itemCategory },
{ ParameterItemId, itemID },
{ ParameterLevelName, levelName },
{ ParameterLevel, level },
{ ParameterSuccess, result == ELevelResult.success ? "true" : "false" },
{ ParameterResult, result.ToString() },
{ ParameterReplay, isReplay ? "true" : "false"},
};
if (duration != null)
dict[ParameterDuration] = duration.Value;
if(step != null)
dict[ParameterStep] = step.Value;
if(score != null)
dict[ParameterScore] = score.Value;
if(extra != null) dict.AddRange(extra, isOverride:true);
LogEvent(EventLevelEnd, dict);
if (result == ELevelResult.success)
{
int lv = BPlay;
if (lv == 0) lv = level;
LevelEndSuccess(itemCategory, lv, itemID);
}
}
/// <summary>
/// 关卡结束(Firebase标准事件)
/// </summary>
/// <param name="level"></param>
/// <param name="result"></param>
/// <param name="levelName"></param>
/// <param name="itemCategory"></param>
/// <param name="itemId"></param>
/// <param name="duration"></param>
/// <param name="step"></param>
/// <param name="score"></param>
/// <param name="extra"></param>
public static void LogLevelEnd(int level, string result,
string levelName = "", string itemCategory = "main", string itemId = "",
int? duration = null, int? step = null, int? score = null, Dictionary<string, object> extra = null)
{
bool isSuccess = result.Equals("success");
var dict = new Dictionary<string, object>()
{
{ ParameterItemCategory, itemCategory },
{ ParameterItemId, itemId },
{ ParameterLevelName, levelName },
{ ParameterLevel, level },
{ ParameterSuccess, isSuccess ? "true" : "false" },
{ ParameterResult, result },
};
if (duration != null)
dict[ParameterDuration] = duration.Value;
if(step != null)
dict[ParameterStep] = step.Value;
if(score != null)
dict[ParameterScore] = score.Value;
if(extra != null) dict.AddRange(extra, isOverride:true);
LogEvent(EventLevelEnd, dict);
if (isSuccess)
{
int lv = BPlay;
if (lv == 0) lv = level;
LevelEndSuccess(itemCategory, lv, itemId);
}
}
/// <summary>
/// 新用户通过第几关仅记录前n关,根据项目自行确定,不区分关卡类型)[买量用]
/// </summary>
/// <param name="itemCategory"></param>
/// <param name="level">关卡从1开始</param>
/// /// <param name="itemID">棋局id /图片id</param>
public static void LevelEndSuccess(string itemCategory, int level, string itemID)
{
if (level > GuruSettings.Instance.AnalyticsSetting.LevelEndSuccessNum)
return;
string eventName = $"level_end_success_{level}";
LogEvent(eventName,new Dictionary<string, object>()
{
{ ParameterItemId, itemID },
{ ParameterItemCategory, itemCategory}
});
}
/// <summary>
/// 第一次通关打点
/// </summary>
private static void LevelFirstEnd(string itemCategory, string itemID, string levelName, int level,
ELevelResult result, int? duration = null, int? step = null, int? score = null)
{
var dict = new Dictionary<string, object>()
{
{ ParameterItemCategory, itemCategory },
{ ParameterItemId, itemID },
{ ParameterLevelName, levelName },
{ ParameterLevel, level },
{ ParameterSuccess, result == ELevelResult.success ? 1 : 0 },
{ ParameterResult, result.ToString() },
};
if (duration != null)
dict[ParameterDuration] = duration.Value;
if(step != null)
dict[ParameterStep] = step.Value;
if(score != null)
dict[ParameterScore] = score.Value;
}
#endregion
#region Coins
/// <summary>
/// 当用户获取了虚拟货币(金币、宝石、代币等)时触发
/// </summary>
/// <param name="virtual_currency_name">虚拟货币的名称</param>
/// <param name="value">虚拟货币的数量</param>
/// <param name="item_category">金币获取的方式通过IAP购买的方式固定使用<iap_buy>参数值,其余场景自行定义。</param>
/// <param name="balance">玩家当前剩余的虚拟货币数量</param>
/// <param name="sku">购买商品的product_id(购买时传参)</param>
public static void EarnVirtualCurrency(string virtual_currency_name, int value, string item_category,
int balance, string sku, Dictionary<string, object> extra = null)
{
var dict = new Dictionary<string, object>()
{
[ParameterVirtualCurrencyName] = virtual_currency_name,
[ParameterValue] = value,
[ParameterItemCategory] = item_category,
["balance"] = balance,
["sku"] = sku,
};
if(extra != null) dict.AddRange(extra, isOverride: true);
LogEvent(EventEarnVirtualCurrency, dict);
}
/// <summary>
/// 当用户支出了虚拟货币(金币、宝石、代币等)时触发
/// </summary>
/// <param name="virtual_currency_name">虚拟货币的名称</param>
/// <param name="value">虚拟货币的数量</param>
/// <param name="item_category">虚拟货币花费场景</param>
/// <param name="balance">玩家当前剩余的虚拟货币数量</param>
public static void SpendVirtualCurrency(string virtual_currency_name, int value, string item_category,
int balance, Dictionary<string, object> extra = null)
{
var dict = new Dictionary<string, object>()
{
[ParameterVirtualCurrencyName] = virtual_currency_name,
[ParameterValue] = value,
[ParameterItemCategory] = item_category,
["balance"] = balance,
};
if(extra != null) dict.AddRange(extra, isOverride: true);
LogEvent(EventSpendVirtualCurrency, dict);
}
#endregion
#region HP
/// <summary>
/// 体力变化时触发
/// </summary>
/// <param name="item_category">体力变化的场景</param>
/// <param name="hp_before">本次行为变化前体力</param>
/// <param name="hp">本次行为带来的体力</param>
/// <param name="hp_after">本次行为变化后体力</param>
public static void HitPoints(string item_category, int hp_before, int hp, int hp_after, Dictionary<string, object> extra = null)
{
var dict = new Dictionary<string, object>()
{
[ParameterItemCategory] = item_category,
["hp_before"] = hp_before,
["hp"] = hp,
["hp_after"] = hp_after,
};
if(extra != null) dict.AddRange(extra, isOverride: true);
LogEvent("hit_points", dict);
}
#endregion
#region Tch 太极打点逻辑
private static double _tch001MaxValue = 5.0d; // 预设保护值, 如果大于这个值, 算作异常上报
private static double _tch001TargetValue = 0.01d;
public static double Tch001TargetValue => _tch001TargetValue; // 太极 001 设定值
private static double _tch02TargetValue = 0.20d;
public static double Tch02TargetValue => _tch02TargetValue; // 太极 02 设定值
public static string IAPPlatform
{
get
{
#if UNITY_IOS
return "appstore";
#endif
return "google_play";
}
}
public static bool EnableTch02Event { get; set; } = false; // 是否使用太极02事件(请手动开启)
/// <summary>
/// 太极001 IAP收入
/// 每发生一次iap收入触发一次该事件value值为本次iap的收入值
/// </summary>
/// <param name="value">中台返回地收入值</param>
/// <param name="productId"></param>
/// <param name="orderId"></param>
/// <param name="orderType"></param>
/// <param name="timestamp"></param>
public static void Tch001IAPRev(double value, string productId, string orderId, string orderType, string timestamp)
{
TchRevEvent(EventTchAdRev001Impression, IAPPlatform, value, orderType, productId, orderId, timestamp);
if(EnableTch02Event) return; // 如果使用了太极02 则不做FB上报
FBPurchase(value, USD, "iap", IAPPlatform);
}
/// <summary>
/// 太极02 IAP 收入打点
/// 发生一次iap收入触发一次该事件value值为本次iap的收入值
/// </summary>
/// <param name="value"></param>
/// <param name="productId"></param>
/// <param name="orderId"></param>
/// <param name="orderType"></param>
/// <param name="timestamp"></param>
// public static void Tch02IAPRev(double value, string productId, string orderId, string orderType, string timestamp)
public static void Tch02IAPRev(double value)
{
if (!EnableTch02Event) return;
TchRevEvent(EventTchAdRev02Impression, IAPPlatform, value);
FBPurchase(value, USD, "iap", IAPPlatform);
}
/// <summary>
/// "1.广告收入累计超过0.01美元,触发一次该事件,重新清零后,开始下一次累计计算;
/// </summary>
/// <param name="value"></param>
public static void Tch001ADRev(double value)
{
if (value > _tch001MaxValue)
{
TchAdAbnormalEvent(value); // 上报异常值
return;
}
// if (value < Tch001TargetValue) value = Tch001TargetValue; // TCH广告添加0值校验修复, 不得小于0.01
TchRevEvent(EventTchAdRev001Impression, AdMAX, value);
if(EnableTch02Event) return; // 如果使用了太极02 则不做FB上报
//FB标准购买事件
FBPurchase(value, USD, "ads", AdMAX);
}
/// <summary>
/// "1.5 广告收入累计超过0.2美元,触发一次该事件,重新清零后,开始下一次累计计算;
/// </summary>
/// <param name="value"></param>
public static void Tch02ADRev(double value)
{
if (!EnableTch02Event) return;
// if (value < Tch02TargetValue) value = Tch02TargetValue; // TCH广告添加0值校验修复
TchRevEvent(EventTchAdRev02Impression, AdMAX, value);
//FB标准购买事件
FBPurchase(value, USD, "ads", AdMAX);
}
/// <summary>
/// 太极事件点位上报
/// </summary>
/// <param name="evtName"></param>
/// <param name="platform"></param>
/// <param name="value"></param>
/// <param name="orderType"></param>
/// <param name="productId"></param>
/// <param name="orderId"></param>
/// <param name="timestamp"></param>
private static void TchRevEvent(string evtName, string platform, double value,
string orderType = "", string productId = "", string orderId = "", string timestamp = "")
{
var data = new Dictionary<string, dynamic>()
{
{ ParameterAdPlatform, platform },
{ ParameterValue, value },
{ ParameterCurrency, USD },
};
//--------- Extra data for IAP receipt ---------------
if(!string.IsNullOrEmpty(orderType)) data["order_type"] = orderType;
if(!string.IsNullOrEmpty(productId)) data["product_id"] = productId;
if(!string.IsNullOrEmpty(orderId)) data["order_id"] = orderId;
if(!string.IsNullOrEmpty(timestamp)) data["trans_ts"] = timestamp;
//--------- Extra data for IAP receipt ---------------
LogEvent(evtName, data);
}
/// <summary>
/// Facebook 支付上报
/// </summary>
/// <param name="revenue"></param>
/// <param name="currency"></param>
/// <param name="type"></param>
/// <param name="platfrom"></param>
public static void FBPurchase(decimal revenue, string currency, string type, string platfrom)
{
FB.LogPurchase(revenue, currency, new Dictionary<string, object>()
{
{ AppEventParameterName.Currency, USD },
{ AppEventParameterName.ContentType, type },
{ ParameterAdPlatform, platfrom},
});
}
/// <summary>
/// Facebook 支付上报
/// </summary>
/// <param name="value"></param>
/// <param name="currency"></param>
/// <param name="type"></param>
/// <param name="platfrom"></param>
public static void FBPurchase(double value, string currency, string type, string platfrom)
=> FBPurchase(Convert.ToDecimal(value), currency, type, platfrom);
/// <summary>
/// Google ARO买量点
/// </summary>
/// <param name="impressionData">广告收入数据</param>
/// <a href="https://docs.google.com/spreadsheets/d/1lFWLeOGJgq34QDBTfl6OpNh7MoI37ehGrhdbxlOrJgs/edit#gid=983654222"></a>
/// <li>
/// value double eg0.002
/// currency string USD(只传美元)
/// ad_platform string "MAX | ADMOB | FACEBOOK"
/// ad_source string 广告来源
/// ad_format string 广告格式
/// ad_unit_name string 广告位名称
/// ad_creative_id string 广告素材id
/// </li>
public static void ADImpression(MaxSdkBase.AdInfo impressionData)
{
double revenue = impressionData.Revenue;
LogEvent(EventAdImpression, new Dictionary<string, dynamic>()
{
[ParameterValue] = revenue,
[ParameterCurrency] = USD,
[ParameterAdPlatform] = AdMAX,
[ParameterAdSource] = impressionData.NetworkName,
[ParameterAdFormat] = impressionData.AdFormat,
[ParameterAdUnitName] = impressionData.AdUnitIdentifier,
[ParameterAdCreativeId] = impressionData.CreativeIdentifier,
});
}
public static void TchAdAbnormalEvent(double value)
{
LogEvent(EventTchAdRevAbnormal, new Dictionary<string, dynamic>()
{
{ ParameterAdPlatform, AdMAX },
{ ParameterCurrency, USD },
{ ParameterValue, value },
});
}
#endregion
#region Analytics Game IAP 游戏内购打点
/// <summary>
/// app 内弹出的付费引导
/// </summary>
/// <param name="itemCategory">界面跳转的来源</param>
/// <param name="productID">product id,多个产品用逗号分隔第一个商品id放主推商品id</param>
public static void IAPImp(string itemCategory, string productID)
{
LogEvent(EventIAPImp, new Dictionary<string, object>()
{
{ ParameterItemCategory, itemCategory },
{ ParameterItemName, productID },
});
}
/// <summary>
/// app 内弹出的付费引导
/// </summary>
/// <param name="itemCategory">界面跳转的来源</param>
/// <param name="productID">product id,多个产品用逗号分隔第一个商品id放主推商品id</param>
public static void IAPClose(string itemCategory, string productID)
{
LogEvent(EventIAPClose, new Dictionary<string, object>()
{
{ ParameterItemCategory, itemCategory },
{ ParameterItemName, productID },
});
}
/// <summary>
/// app 内弹出的付费引导
/// </summary>
/// <param name="itemCategory">界面跳转的来源</param>
/// <param name="productID">product id,多个产品用逗号分隔第一个商品id放主推商品id</param>
public static void IAPClick(string itemCategory, string productID)
{
LogEvent(EventIAPClick, new Dictionary<string, object>()
{
{ ParameterItemCategory, itemCategory },
{ ParameterItemName, productID },
});
}
/// <summary>
/// "app 内弹出的付费引导IAP付费或试用成功打点"
/// </summary>
/// <param name="scene">界面跳转的来源</param>
/// <param name="productId">product id,多个产品用逗号分隔第一个商品id放主推商品id</param>
/// <param name="value">产品的价格</param>
/// <param name="currency">用户的付费币种</param>
/// <param name="orderId">订单 ID</param>
/// <param name="type">付费类型订阅/产品subscription/product</param>
/// <param name="isfree">是否为试用1试用0付费</param>
public static void IAPRetTrue(string scene, string productId, double value, string currency, string orderId, string type, bool isfree)
{
LogEvent(EventIAPReturnTrue, new Dictionary<string, object>()
{
{ ParameterItemCategory, scene },
{ ParameterItemName, productId },
{ ParameterValue, value },
{ ParameterCurrency, currency },
{ "order_id", orderId },
{ "type", type },
{ "isfree", isfree ? 1 : 0 },
});
}
/// <summary>
/// "app 内弹出的付费引导IAP付费或试用失败打点"
/// </summary>
/// <param name="itemCategory">界面跳转的来源</param>
/// <param name="productID">product id,多个产品用逗号分隔第一个商品id放主推商品id</param>
public static void IAPRetFalse(string itemCategory, string productID, string failReason)
{
LogEvent(EventIAPReturnFalse, new Dictionary<string, object>()
{
{ ParameterItemCategory, itemCategory },
{ ParameterItemName, productID },
});
}
/// <summary>
/// 新用户首次 IAP 付费成功上报 (仅限应用内付费商品,不包含订阅等其它情况)【买量打点】
/// </summary>
/// <param name="itemName">productId 商品ID</param>
/// <param name="value">付费总金额</param>
/// <param name="currency">币种</param>
public static void FirstIAP(string itemName, double value, string currency)
{
LogEvent(EventIAPFirst, new Dictionary<string, object>()
{
{ ParameterItemName, itemName },
{ ParameterValue, value },
{ ParameterCurrency, currency },
});
}
/// <summary>
/// 商品购买成功上报【买量打点】
/// </summary>
/// <param name="productName">商品名称商品ID一样</param>
/// <param name="itemName">productId 商品ID</param>
/// <param name="value">付费总金额</param>
/// <param name="currency">币种</param>
public static void ProductIAP(string productName, string itemName, double value, string currency)
{
// 替换SKU中的 "." -> "_", 比如: "do.a.iapc.coin.100" 转换为 "do_a_iapc_coin_100"
if (productName.Contains(".")) productName = productName.Replace(".", "_");
string eventName = $"iap_{productName}";
LogEvent(eventName, new Dictionary<string, object>()
{
{ ParameterItemName, itemName },
{ ParameterValue, value },
{ ParameterCurrency, currency },
});
}
/// <summary>
/// 支付成功后统一上报所有点位数据
/// </summary>
/// <param name="productId"></param>
/// <param name="usdPrice"></param>
/// <param name="userCurrency"></param>
/// <param name="payPrice"></param>
/// <param name="orderId"></param>
/// <param name="orderType"></param>
/// <param name="orderDate"></param>
/// <param name="scene"></param>
/// <param name="isFree"></param>
public static void ReportIAPSuccessEvent(double usdPrice, string productId, BaseOrderData orderData)
{
string userCurrency = orderData.userCurrency;
double payPrice = orderData.payPrice;
string orderType = orderData.OrderType();
string orderType2 = orderData.OrderTypeII();
string orderId = orderData.orderId;
string orderDate = orderData.payedDate;
string scene = orderData.scene;
bool isFree = orderData.isFree;
// TCH 001
Tch001IAPRev(usdPrice, productId, orderId, orderType, orderDate);
// TCH 020
Tch02IAPRev(usdPrice);
// Adjust Track IAP Purchase
AdjustService.TrackIAPPurchase(usdPrice, productId); // 上报 IAP 支付事件
if (orderData.orderType == 1)
{
// sub_pruchase
SubPurchase(usdPrice, productId, orderId, orderDate);
}
else
{
// iap_purchase
IAPPurchase(usdPrice, productId, orderId, orderDate);
}
// IAP Ret true
IAPRetTrue(scene, productId, payPrice, userCurrency, orderId, orderType2, isFree);
}
#endregion
#region IAP_PURCHASE
/// <summary>
/// IAP 内购上报
/// </summary>
/// <param name="value"></param>
/// <param name="productId"></param>
/// <param name="orderId"></param>
/// <param name="orderDate"></param>
public static void IAPPurchase(double value, string productId, string orderId, string orderDate)
{
IAPPurchaseReport(EventIAPPurchase, value, productId, orderId, "IAP", orderDate);
}
public static void SubPurchase(double value, string productId, string orderId, string orderDate)
{
IAPPurchaseReport(EventSubPurchase, value, productId, orderId, "SUB", orderDate);
}
private static void IAPPurchaseReport(string eventName, double value, string productId, string orderId, string orderType, string orderDate)
{
LogEvent(eventName, new Dictionary<string, dynamic>()
{
[ParameterAdPlatform] = IAPPlatform,
[ParameterPlatform] = IAPPlatform,
[ParameterCurrency] = USD,
[ParameterValue] = value,
["product_id"] = productId,
["order_id"] = orderId,
["order_type"] = orderType,
["trans_ts"] = orderDate
}, new EventSetting()
{
EnableFirebaseAnalytics = true,
EnableAdjustAnalytics = true,
});
}
#endregion
#region 中台异常打点
/// <summary>
/// 中台异常打点
/// </summary>
/// <param name="data"></param>
public static void LogDevAudit(Dictionary<string, dynamic> data)
{
if (data == null) return;
data["country"] = IPMConfig.IPM_COUNTRY_CODE;
data["network"] = Application.internetReachability.ToString();
LogEvent(EventDevAudit, data, new EventSetting() { EnableFirebaseAnalytics = true });
}
#endregion
}
}