Skip to content

Commit 08beaef

Browse files
Add Firebase Database ServerValue increment binding (#117)
1 parent 090809c commit 08beaef

3 files changed

Lines changed: 91 additions & 0 deletions

File tree

source/Firebase/Database/ApiDefinition.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,11 @@ interface ServerValue
595595
[Static]
596596
[Export ("timestamp")]
597597
NSDictionary Timestamp { get; }
598+
599+
// +(NSDictionary * _Nonnull)increment:(NSNumber * _Nonnull)delta;
600+
[Static]
601+
[Export ("increment:")]
602+
NSDictionary Increment (NSNumber delta);
598603
}
599604

600605
// @interface FIRTransactionResult : NSObject

tests/E2E/Firebase.Foundation/FirebaseFoundationE2E/FirebaseRuntimeDriftCases.cs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
using System.Reflection;
22

3+
#if ENABLE_RUNTIME_DRIFT_CASE_DATABASE_SERVERVALUE_INCREMENT
4+
using Firebase.Database;
5+
using Foundation;
6+
using ObjCRuntime;
7+
#endif
8+
39
#if ENABLE_RUNTIME_DRIFT_CASE_ABTESTING_UPDATEEXPERIMENTS
410
using Firebase.ABTesting;
511
using Foundation;
@@ -78,6 +84,75 @@ public static async Task<string> ExecuteConfiguredCaseAsync()
7884
?.Value;
7985
}
8086

87+
#if ENABLE_RUNTIME_DRIFT_CASE_DATABASE_SERVERVALUE_INCREMENT
88+
static Task<string> VerifyDatabaseServerValueIncrementAsync()
89+
{
90+
const string selector = "increment:";
91+
92+
var signature = typeof(ServerValue).GetMethod(
93+
nameof(ServerValue.Increment),
94+
BindingFlags.Static | BindingFlags.Public,
95+
binder: null,
96+
types: new[] { typeof(NSNumber) },
97+
modifiers: null);
98+
if (signature is null)
99+
{
100+
throw new InvalidOperationException(
101+
$"Expected managed API '{nameof(ServerValue.Increment)}({typeof(NSNumber).FullName})' was not found.");
102+
}
103+
104+
using var delta = NSNumber.FromInt64(1);
105+
NSException? marshaledException = null;
106+
MarshalObjectiveCExceptionMode? marshaledExceptionMode = null;
107+
108+
void OnMarshalObjectiveCException(object? sender, MarshalObjectiveCExceptionEventArgs args)
109+
{
110+
marshaledException ??= args.Exception;
111+
marshaledExceptionMode ??= args.ExceptionMode;
112+
}
113+
114+
Runtime.MarshalObjectiveCException += OnMarshalObjectiveCException;
115+
try
116+
{
117+
NSDictionary placeholder;
118+
try
119+
{
120+
placeholder = ServerValue.Increment(delta);
121+
}
122+
catch (ObjCException ex)
123+
{
124+
throw new InvalidOperationException(
125+
$"Selector '{selector}' should not throw for a valid NSNumber delta, but observed {ex.GetType().FullName}. " +
126+
$"Managed delta argument type: {delta.GetType().FullName}. " +
127+
$"NSException.Name: {FormatDetail(marshaledException?.Name?.ToString())}. " +
128+
$"NSException.Reason: {FormatDetail(marshaledException?.Reason)}. " +
129+
$"Marshal mode: {FormatDetail(marshaledExceptionMode?.ToString())}.",
130+
ex);
131+
}
132+
133+
if (marshaledException is not null)
134+
{
135+
throw new InvalidOperationException(
136+
$"Selector '{selector}' completed, but Runtime.MarshalObjectiveCException captured unexpected NSException.Name '{marshaledException.Name}'. " +
137+
$"Reason: {FormatDetail(marshaledException.Reason)}. Marshal mode: {FormatDetail(marshaledExceptionMode?.ToString())}.");
138+
}
139+
140+
if (placeholder.Count == 0)
141+
{
142+
throw new InvalidOperationException("ServerValue.Increment returned an empty placeholder dictionary.");
143+
}
144+
145+
return Task.FromResult(
146+
$"Selector '{selector}' returned a non-empty placeholder dictionary. " +
147+
$"Managed delta argument type: {delta.GetType().FullName}. Placeholder count: {placeholder.Count}.");
148+
}
149+
finally
150+
{
151+
Runtime.MarshalObjectiveCException -= OnMarshalObjectiveCException;
152+
}
153+
}
154+
#endif
155+
81156
#if ENABLE_RUNTIME_DRIFT_CASE_ABTESTING_UPDATEEXPERIMENTS
82157
static async Task<string> VerifyABTestingUpdateExperimentsAsync()
83158
{

tests/E2E/Firebase.Foundation/runtime-drift-cases.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
{
22
"cases": [
3+
{
4+
"id": "database-servervalue-increment",
5+
"method": "VerifyDatabaseServerValueIncrementAsync",
6+
"bindingPackage": "AdamE.Firebase.iOS.Database",
7+
"packages": [
8+
{
9+
"id": "AdamE.Firebase.iOS.Database",
10+
"version": "12.6.0"
11+
}
12+
]
13+
},
314
{
415
"id": "abtesting-updateexperiments",
516
"method": "VerifyABTestingUpdateExperimentsAsync",

0 commit comments

Comments
 (0)