fixes, improvements. firebase

This commit is contained in:
Savya Bikram Shah
2026-06-01 13:15:40 +05:45
parent 384176fdcc
commit 6f79bcd018
180 changed files with 25324 additions and 9393 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d8f2a4a0f471748a1865f7d363c9bdc6
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,6 @@
using System.Runtime.CompilerServices;
// Grant native C# Unity packages access to Firebase.App's internal helpers
[assembly: InternalsVisibleTo("Firebase.Functions")]
[assembly: InternalsVisibleTo("Firebase.FirebaseAI")]
[assembly: InternalsVisibleTo("Firebase.FirebaseAI.TestApp")]

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d640bc2403824e5599315e0050b99aeb
labels:
- gvh
- gvh_version-13.11.0
- gvhp_exportpath-Firebase/FirebaseApp/Internal/AssemblyInfo.cs
timeCreated: 1480838400
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,17 @@
{
"name": "Firebase.App.Internal",
"rootNamespace": "Firebase.Internal",
"references": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": true,
"precompiledReferences": [
"Firebase.App.dll",
"Firebase.Platform.dll"
],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9b4ce77d2be44f25af03d4cbf9bee9f9
labels:
- gvh
- gvh_version-13.11.0
- gvhp_exportpath-Firebase/FirebaseApp/Internal/Firebase.App.Internal.asmdef
timeCreated: 1480838400
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,461 @@
/*
* Copyright 2025 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Net.Http;
using System.Net.WebSockets;
using System.Reflection;
using System.Threading.Tasks;
namespace Firebase.Internal
{
// Contains internal helper methods for interacting with other Firebase libraries.
internal static class FirebaseInterops
{
// The cached fields for FirebaseApp reflection.
private static PropertyInfo _dataCollectionProperty = null;
// The various App Check types needed to retrieve the token, cached via reflection on startup.
private static Type _appCheckType;
private static MethodInfo _appCheckGetInstanceMethod;
private static MethodInfo _appCheckGetTokenMethod;
private static MethodInfo _appCheckGetLimitedUseTokenMethod;
private static PropertyInfo _appCheckTokenResultProperty;
private static PropertyInfo _appCheckTokenTokenProperty;
// Used to determine if the App Check reflection initialized successfully, and should work.
private static bool _appCheckReflectionInitialized = false;
// The header used by the AppCheck token.
private const string appCheckHeader = "X-Firebase-AppCheck";
// The various Auth types needed to retrieve the token, cached via reflection on startup.
private static Type _authType;
private static MethodInfo _authGetAuthMethod;
private static PropertyInfo _authCurrentUserProperty;
private static MethodInfo _userTokenAsyncMethod;
private static PropertyInfo _userTokenTaskResultProperty;
// Used to determine if the Auth reflection initialized successfully, and should work.
private static bool _authReflectionInitialized = false;
// The header used by the AppCheck token.
private const string authHeader = "Authorization";
static FirebaseInterops()
{
InitializeAppReflection();
InitializeAppCheckReflection();
InitializeAuthReflection();
}
private static void LogError(string message)
{
#if FIREBASEAI_DEBUG_LOGGING
UnityEngine.Debug.LogError(message);
#endif
}
// Cache the methods needed for FirebaseApp reflection.
private static void InitializeAppReflection()
{
try
{
_dataCollectionProperty = typeof(FirebaseApp).GetProperty(
"IsDataCollectionDefaultEnabled",
BindingFlags.Instance | BindingFlags.NonPublic);
if (_dataCollectionProperty == null)
{
LogError("Could not find FirebaseApp.IsDataCollectionDefaultEnabled property via reflection.");
return;
}
if (_dataCollectionProperty.PropertyType != typeof(bool))
{
LogError("FirebaseApp.IsDataCollectionDefaultEnabled is not a bool, " +
$"but is {_dataCollectionProperty.PropertyType}");
return;
}
}
catch (Exception e)
{
LogError($"Failed to initialize FirebaseApp reflection: {e}");
}
}
// Gets the property FirebaseApp.IsDataCollectionDefaultEnabled.
public static bool GetIsDataCollectionDefaultEnabled(FirebaseApp firebaseApp)
{
if (firebaseApp == null || _dataCollectionProperty == null)
{
return false;
}
try
{
return (bool)_dataCollectionProperty.GetValue(firebaseApp);
}
catch (Exception e)
{
LogError($"Error accessing 'IsDataCollectionDefaultEnabled': {e}");
return false;
}
}
// SDK version to use if unable to find it.
private const string _unknownSdkVersion = "unknown";
private static readonly Lazy<string> _sdkVersionFetcher = new(() =>
{
try
{
// Get the type Firebase.VersionInfo from the assembly that defines FirebaseApp.
Type versionInfoType = typeof(FirebaseApp).Assembly.GetType("Firebase.VersionInfo");
if (versionInfoType == null)
{
LogError("Firebase.VersionInfo type not found via reflection");
return _unknownSdkVersion;
}
// Firebase.VersionInfo.SdkVersion
PropertyInfo sdkVersionProperty = versionInfoType.GetProperty(
"SdkVersion",
BindingFlags.Static | BindingFlags.NonPublic);
if (sdkVersionProperty == null)
{
LogError("Firebase.VersionInfo.SdkVersion property not found via reflection.");
return _unknownSdkVersion;
}
return sdkVersionProperty.GetValue(null) as string ?? _unknownSdkVersion;
}
catch (Exception e)
{
LogError($"Error accessing SdkVersion via reflection: {e}");
return _unknownSdkVersion;
}
});
// Gets the internal property Firebase.VersionInfo.SdkVersion
internal static string GetVersionInfoSdkVersion()
{
return _sdkVersionFetcher.Value;
}
// Cache the various types and methods needed for AppCheck token retrieval.
private static void InitializeAppCheckReflection()
{
const string firebaseAppCheckTypeName = "Firebase.AppCheck.FirebaseAppCheck, Firebase.AppCheck";
const string getAppCheckTokenMethodName = "GetAppCheckTokenAsync";
const string getLimitedUseAppCheckTokenMethodName = "GetLimitedUseAppCheckTokenAsync";
try
{
// Set this to false, to allow easy failing out via return.
_appCheckReflectionInitialized = false;
_appCheckType = Type.GetType(firebaseAppCheckTypeName);
if (_appCheckType == null)
{
return;
}
// Get the static method GetInstance(FirebaseApp app)
_appCheckGetInstanceMethod = _appCheckType.GetMethod(
"GetInstance", BindingFlags.Static | BindingFlags.Public, null,
new Type[] { typeof(FirebaseApp) }, null);
if (_appCheckGetInstanceMethod == null)
{
LogError("Could not find FirebaseAppCheck.GetInstance method via reflection.");
return;
}
// Get the instance method GetAppCheckTokenAsync(bool forceRefresh)
_appCheckGetTokenMethod = _appCheckType.GetMethod(
getAppCheckTokenMethodName, BindingFlags.Instance | BindingFlags.Public, null,
new Type[] { typeof(bool) }, null);
if (_appCheckGetTokenMethod == null)
{
LogError($"Could not find {getAppCheckTokenMethodName} method via reflection.");
return;
}
// Get the instance method GetLimitedUseAppCheckTokenAsync()
_appCheckGetLimitedUseTokenMethod = _appCheckType.GetMethod(
getLimitedUseAppCheckTokenMethodName, BindingFlags.Instance | BindingFlags.Public, null,
Type.EmptyTypes, null);
if (_appCheckGetLimitedUseTokenMethod == null)
{
LogError($"Could not find {getLimitedUseAppCheckTokenMethodName} method via reflection.");
return;
}
// Should be Task<AppCheckToken>
Type appCheckTokenTaskType = _appCheckGetTokenMethod.ReturnType;
// Get the Result property from the Task<AppCheckToken>
_appCheckTokenResultProperty = appCheckTokenTaskType.GetProperty("Result");
if (_appCheckTokenResultProperty == null)
{
LogError("Could not find Result property on App Check token Task.");
return;
}
// Should be AppCheckToken
Type appCheckTokenType = _appCheckTokenResultProperty.PropertyType;
_appCheckTokenTokenProperty = appCheckTokenType.GetProperty("Token");
if (_appCheckTokenTokenProperty == null)
{
LogError($"Could not find Token property on AppCheckToken.");
return;
}
_appCheckReflectionInitialized = true;
}
catch (Exception e)
{
LogError($"Exception during static initialization of FirebaseInterops: {e}");
}
}
// Gets the AppCheck Token, assuming there is one. Otherwise, returns null.
internal static async Task<string> GetAppCheckTokenAsync(FirebaseApp firebaseApp, bool limitedUse = false)
{
// If AppCheck reflection failed for any reason, nothing to do.
if (!_appCheckReflectionInitialized)
{
return null;
}
try
{
// Get the FirebaseAppCheck instance for the current FirebaseApp
object appCheckInstance = _appCheckGetInstanceMethod.Invoke(null, new object[] { firebaseApp });
if (appCheckInstance == null)
{
LogError("Failed to get FirebaseAppCheck instance via reflection.");
return null;
}
object taskObject;
if (limitedUse)
{
taskObject = _appCheckGetLimitedUseTokenMethod.Invoke(appCheckInstance, null);
}
else
{
// Invoke GetAppCheckTokenAsync(false) - returns a Task<AppCheckToken>
taskObject = _appCheckGetTokenMethod.Invoke(appCheckInstance, new object[] { false });
}
if (taskObject is not Task appCheckTokenTask)
{
LogError($"Invoking GetToken did not return a Task.");
return null;
}
// Await the task to get the AppCheckToken result
await appCheckTokenTask;
// Check for exceptions in the task
if (appCheckTokenTask.IsFaulted)
{
LogError($"Error getting App Check token: {appCheckTokenTask.Exception}");
return null;
}
// Get the Result property from the Task<AppCheckToken>
object tokenResult = _appCheckTokenResultProperty.GetValue(appCheckTokenTask); // This is the AppCheckToken struct
if (tokenResult == null)
{
LogError("App Check token result was null.");
return null;
}
// Get the Token property from the AppCheckToken struct
string finalToken = _appCheckTokenTokenProperty.GetValue(tokenResult) as string;
return finalToken;
}
catch (Exception e)
{
// Log any exceptions during the reflection/invocation process
LogError($"An error occurred while trying to fetch App Check token: {e}");
}
return null;
}
// Cache the various types and methods needed for Auth token retrieval.
private static void InitializeAuthReflection()
{
const string firebaseAuthTypeName = "Firebase.Auth.FirebaseAuth, Firebase.Auth";
const string getTokenMethodName = "TokenAsync";
try
{
// Set this to false, to allow easy failing out via return.
_authReflectionInitialized = false;
_authType = Type.GetType(firebaseAuthTypeName);
if (_authType == null)
{
// Auth assembly likely not present, fine to skip
return;
}
// Get the static method GetAuth(FirebaseApp app):
_authGetAuthMethod = _authType.GetMethod(
"GetAuth", BindingFlags.Static | BindingFlags.Public, null,
new Type[] { typeof(FirebaseApp) }, null);
if (_authGetAuthMethod == null)
{
LogError("Could not find FirebaseAuth.GetAuth method via reflection.");
return;
}
// Get the CurrentUser property from FirebaseAuth instance
_authCurrentUserProperty = _authType.GetProperty("CurrentUser", BindingFlags.Instance | BindingFlags.Public);
if (_authCurrentUserProperty == null)
{
LogError("Could not find FirebaseAuth.CurrentUser property via reflection.");
return;
}
// This should be FirebaseUser type
Type userType = _authCurrentUserProperty.PropertyType;
// Get the TokenAsync(bool) method from FirebaseUser
_userTokenAsyncMethod = userType.GetMethod(
getTokenMethodName, BindingFlags.Instance | BindingFlags.Public, null,
new Type[] { typeof(bool) }, null);
if (_userTokenAsyncMethod == null)
{
LogError($"Could not find FirebaseUser.{getTokenMethodName}(bool) method via reflection.");
return;
}
// The return type is Task<string>
Type tokenTaskType = _userTokenAsyncMethod.ReturnType;
// Get the Result property from Task<string>
_userTokenTaskResultProperty = tokenTaskType.GetProperty("Result");
if (_userTokenTaskResultProperty == null)
{
LogError("Could not find Result property on Auth token Task.");
return;
}
// Check if Result property is actually a string
if (_userTokenTaskResultProperty.PropertyType != typeof(string))
{
LogError("Auth token Task's Result property is not a string, " +
$"but is {_userTokenTaskResultProperty.PropertyType}");
return;
}
_authReflectionInitialized = true;
}
catch (Exception e)
{
LogError($"Exception during static initialization of Auth reflection in FirebaseInterops: {e}");
_authReflectionInitialized = false;
}
}
// Gets the Auth Token, assuming there is one. Otherwise, returns null.
internal static async Task<string> GetAuthTokenAsync(FirebaseApp firebaseApp)
{
// If Auth reflection failed for any reason, nothing to do.
if (!_authReflectionInitialized)
{
return null;
}
try
{
// Get the FirebaseAuth instance for the given FirebaseApp.
object authInstance = _authGetAuthMethod.Invoke(null, new object[] { firebaseApp });
if (authInstance == null)
{
LogError("Failed to get FirebaseAuth instance via reflection.");
return null;
}
// Get the CurrentUser property
object currentUser = _authCurrentUserProperty.GetValue(authInstance);
if (currentUser == null)
{
// No user logged in, so no token
return null;
}
// Invoke TokenAsync(false) - returns a Task<string>
object taskObject = _userTokenAsyncMethod.Invoke(currentUser, new object[] { false });
if (taskObject is not Task tokenTask)
{
LogError("Invoking TokenAsync did not return a Task.");
return null;
}
// Await the task to get the token result
await tokenTask;
// Check for exceptions in the task
if (tokenTask.IsFaulted)
{
LogError($"Error getting Auth token: {tokenTask.Exception}");
return null;
}
// Get the Result property (which is the string token)
return _userTokenTaskResultProperty.GetValue(tokenTask) as string;
}
catch (Exception e)
{
// Log any exceptions during the reflection/invocation process
LogError($"An error occurred while trying to fetch Auth token: {e}");
}
return null;
}
// Adds the other Firebase tokens to the HttpRequest, as available.
internal static async Task AddFirebaseTokensAsync(HttpRequestMessage request, FirebaseApp firebaseApp, string authTokenPrefix = "Firebase", bool limitedUseAppCheckTokens = false)
{
string appCheckToken = await GetAppCheckTokenAsync(firebaseApp, limitedUseAppCheckTokens);
if (!string.IsNullOrEmpty(appCheckToken))
{
request.Headers.Add(appCheckHeader, appCheckToken);
}
string authToken = await GetAuthTokenAsync(firebaseApp);
if (!string.IsNullOrEmpty(authToken))
{
request.Headers.Add(authHeader, $"{authTokenPrefix} {authToken}");
}
}
// Adds the other Firebase tokens to the WebSocket, as available.
internal static async Task AddFirebaseTokensAsync(ClientWebSocket socket, FirebaseApp firebaseApp, string authTokenPrefix = "Firebase")
{
string appCheckToken = await GetAppCheckTokenAsync(firebaseApp);
if (!string.IsNullOrEmpty(appCheckToken))
{
socket.Options.SetRequestHeader(appCheckHeader, appCheckToken);
}
string authToken = await GetAuthTokenAsync(firebaseApp);
if (!string.IsNullOrEmpty(authToken))
{
socket.Options.SetRequestHeader(authHeader, $"{authTokenPrefix} {authToken}");
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bc30602676ea492eab91b6ff7cd6ba3b
labels:
- gvh
- gvh_version-13.11.0
- gvhp_exportpath-Firebase/FirebaseApp/Internal/FirebaseInterops.cs
timeCreated: 1480838400
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,89 @@
/*
* Copyright 2025 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
namespace Firebase.Internal
{
// Helper functions to help handling the Http calls.
internal static class HttpHelpers
{
internal static async Task SetRequestHeaders(HttpRequestMessage request, FirebaseApp firebaseApp, string authPrefix = "Firebase", bool limitedUseAppCheckTokens = false)
{
request.Headers.Add("x-goog-api-key", firebaseApp.Options.ApiKey);
string version = FirebaseInterops.GetVersionInfoSdkVersion();
request.Headers.Add("x-goog-api-client", $"gl-csharp/8.0 fire/{version}");
if (FirebaseInterops.GetIsDataCollectionDefaultEnabled(firebaseApp))
{
request.Headers.Add("X-Firebase-AppId", firebaseApp.Options.AppId);
request.Headers.Add("X-Firebase-AppVersion", UnityEngine.Application.version);
}
// Add additional Firebase tokens to the header.
await FirebaseInterops.AddFirebaseTokensAsync(request, firebaseApp, authPrefix, limitedUseAppCheckTokens);
}
// Helper function to throw an exception if the Http Response indicates failure.
// Useful as EnsureSuccessStatusCode can leave out relevant information.
internal static async Task ValidateHttpResponse(HttpResponseMessage response)
{
if (response.IsSuccessStatusCode)
{
return;
}
// Status code indicates failure, try to read the content for more details
string errorContent = "No error content available.";
if (response.Content != null)
{
try
{
errorContent = await response.Content.ReadAsStringAsync();
}
catch (Exception readEx)
{
// Handle being unable to read the content
errorContent = $"Failed to read error content: {readEx.Message}";
}
}
// Construct the exception with as much information as possible.
var ex = new HttpRequestException(
$"HTTP request failed with status code: {(int)response.StatusCode} ({response.ReasonPhrase}).\n" +
$"Error Content: {errorContent}",
null
);
ex.Data["StatusCode"] = response.StatusCode;
throw ex;
}
}
// Extension to get the StatusCode from the exception.
internal static class HttpRequestExceptionExtensions
{
internal static HttpStatusCode? GetStatusCode(this HttpRequestException exception)
{
if (exception.Data.Contains("StatusCode"))
{
return (HttpStatusCode)exception.Data["StatusCode"];
}
return null;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: edaf55a8a9944057852d797b4558bf8a
labels:
- gvh
- gvh_version-13.11.0
- gvhp_exportpath-Firebase/FirebaseApp/Internal/HttpHelpers.cs
timeCreated: 1480838400
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
<linker>
<assembly fullname="Firebase.Auth">
<type fullname="Firebase.Auth.FirebaseAuth" preserve="all"/>
<type fullname="Firebase.Auth.FirebaseUser" preserve="all"/>
</assembly>
<assembly fullname="Firebase.AppCheck">
<type fullname="Firebase.AppCheck.FirebaseAppCheck" preserve="all"/>
</assembly>
</linker>

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 178c4b1924574f9c95f7a7f28adfd218
labels:
- gvh
- gvh_version-13.11.0
- gvhp_exportpath-Firebase/FirebaseApp/Internal/link.xml
timeCreated: 1480838400
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant: