diff --git a/analytics/src/FirebaseAnalytics.cs b/analytics/src/FirebaseAnalytics.cs
index 200b3513..1449b6b2 100644
--- a/analytics/src/FirebaseAnalytics.cs
+++ b/analytics/src/FirebaseAnalytics.cs
@@ -354,6 +354,25 @@ public static void SetUserId(string userId) {
public static void SetUserProperty(string name, string property) {
FirebaseAnalyticsInternal.SetUserProperty(name, property);
}
+
+ ///
+ /// Logs an in-app purchase transaction specifically for Apple's StoreKit 2.
+ ///
+ ///
+ /// This method is intended for Unity developers on iOS who process transactions
+ /// via In-app purchases and need whish to log those purchases through Google Analytics.
+ /// The provided ID must map 1:1 with the native Apple `Transaction.id`.
+ /// If a matching transaction is not found in the apple devices purchase history then
+ /// nothing will be logged to analytics.
+ ///
+ ///
+ /// The native Apple transaction identifier (e.g.,
+ /// extracted from Unity IAP's purchasedProduct.transactionID).
+ /// A Task that completes when the native StoreKit 2 transaction
+ /// is successfully located and logged.
+ public static System.Threading.Tasks.Task LogAppleTransactionAsync(string transactionId) {
+ return FirebaseAnalyticsInternal.LogAppleTransactionAsync(transactionId);
+ }
}
}
diff --git a/analytics/src/swig/analytics.i b/analytics/src/swig/analytics.i
index 95d48b0b..cd42a3aa 100644
--- a/analytics/src/swig/analytics.i
+++ b/analytics/src/swig/analytics.i
@@ -136,6 +136,7 @@ void SetConsentWithInts(const std::map& settings) {
// GetSessionId returns Future in SWIG.
%include "app/src/swig/future.i"
%SWIG_FUTURE(Future_LongLong, long, internal, long long, FirebaseException)
+%SWIG_FUTURE(FutureVoid, void, internal, void, FirebaseException)
// Ignore the Consent enums, so we can use commented ones in C#
%ignore firebase::analytics::ConsentType;
diff --git a/analytics/testapp/Assets/Firebase/Sample/Analytics/UIHandler.cs b/analytics/testapp/Assets/Firebase/Sample/Analytics/UIHandler.cs
index 08564b79..06367b9d 100644
--- a/analytics/testapp/Assets/Firebase/Sample/Analytics/UIHandler.cs
+++ b/analytics/testapp/Assets/Firebase/Sample/Analytics/UIHandler.cs
@@ -192,6 +192,21 @@ public Task DisplaySessionId() {
}).Unwrap();
}
+ // Log a dummy Apple transaction
+ public Task DisplayLogAppleTransaction() {
+ return FirebaseAnalytics.LogAppleTransactionAsync("dummy_transaction_id").ContinueWithOnMainThread(task => {
+ if (task.IsCanceled) {
+ DebugLog("LogAppleTransaction was canceled.");
+ } else if (task.IsFaulted) {
+ DebugLog(String.Format("Encountered an error logging Apple transaction: {0}",
+ task.Exception.ToString()));
+ } else if (task.IsCompleted) {
+ DebugLog("LogAppleTransaction completed successfully.");
+ }
+ return task;
+ }).Unwrap();
+ }
+
// Output text to the debug log text field, as well as the console.
public void DebugLog(string s) {
print(s);
@@ -257,6 +272,9 @@ void GUIDisplayControls() {
if (GUILayout.Button("Test SetConsent")) {
AnalyticsSetConsent();
}
+ if (GUILayout.Button("Test LogAppleTransaction")) {
+ DisplayLogAppleTransaction();
+ }
GUILayout.EndVertical();
GUILayout.EndScrollView();
}
diff --git a/analytics/testapp/Assets/Firebase/Sample/Analytics/UIHandlerAutomated.cs b/analytics/testapp/Assets/Firebase/Sample/Analytics/UIHandlerAutomated.cs
index c299f4f6..b0b5aad6 100644
--- a/analytics/testapp/Assets/Firebase/Sample/Analytics/UIHandlerAutomated.cs
+++ b/analytics/testapp/Assets/Firebase/Sample/Analytics/UIHandlerAutomated.cs
@@ -43,6 +43,7 @@ public override void Start() {
// Temporarily disabled until this test is deflaked. b/143603151
//TestCheckAndFixDependenciesInvalidOperation,
TestCheckAndFixDependenciesDoubleCall,
+ TestLogAppleTransaction,
};
testRunner = AutomatedTestRunner.CreateTestRunner(
testsToRun: tests,
@@ -254,5 +255,32 @@ Task TestResetAnalyticsData() {
});
return tcs.Task;
}
+
+ Task TestLogAppleTransaction() {
+ // On iOS, this should fail with a dummy ID if no simulated transaction is set up.
+ // On other platforms, it should be a no-op and succeed.
+ if (Application.platform == RuntimePlatform.IPhonePlayer) {
+ return base.DisplayLogAppleTransaction()
+ .ContinueWithOnMainThread(t => {
+ if (t.IsFaulted) {
+ DebugLog("LogAppleTransaction failed as expected with dummy ID.");
+ DebugLog("Exception: " + t.Exception);
+ return true;
+ } else {
+ DebugLog("LogAppleTransaction unexpectedly succeeded with dummy ID.");
+ return true;
+ }
+ });
+ } else {
+ return base.DisplayLogAppleTransaction()
+ .ContinueWithOnMainThread(t => {
+ if (t.IsFaulted) {
+ throw t.Exception;
+ }
+ DebugLog("LogAppleTransaction completed successfully (no-op) on this platform.");
+ return true;
+ });
+ }
+ }
}
}
diff --git a/analytics/testapp/readme.md b/analytics/testapp/readme.md
index a5d02b7f..77af589f 100644
--- a/analytics/testapp/readme.md
+++ b/analytics/testapp/readme.md
@@ -187,6 +187,35 @@ Press some of the buttons to log some events to your Firebase project.
After around 5 hours, data should be visible under the *Analytics* tab in
the [Firebase Console](https://firebase.google.com/console/)).
+## iOS Testing LogAppleTransaction
+
+To test the log apple transaction function, you should use the exported Xcode project and Xcode's simulated transactions.
+The manual test will involve running the testapp and verifying that it logs a transaction to the console.
+
+ - Step 1: Set up the Local Xcode Environment
+ - After building the sample for iOS and opening the exported project in Xcode:
+ - In Xcode, go to File > New > File from Template and create a StoreKit Configuration File (.storekit).
+ - Give the configuration any name.
+ - Target the `Unity-iPhone` scheme (or the relevant target for your exported app).
+ - Add at least one dummy product to this file.
+ - Do this by selecting the file in Xcode and clicking the + button in the bottom left corner.
+ - Choose a Consumable in app purchase product.
+ - Give it a Reference name of your choice (e.g. "ReferenceAppleIapProduct").
+ - Give it a Product ID of your choice (e.g. "com.example.nonconsumable").
+ - Make the app use the store kit file. In the top bar go to Product > Scheme > Edit Scheme...
+ - In the left hand menu select Run
+ - Select the Options tab on the top
+ - Set the StoreKit Configuration dropdown to your new .storekit file.
+ - Step 2: Validate logging transactions
+ - You can create a simulated transaction for testing.
+ - To create a simulated transaction ID:
+ - Go to Debug > StoreKit > Manage Transactions.
+ - Click the + button in the bottom left corner.
+ - Select the Consumable in app purchase product.
+ - Use the generated transaction ID in your code or test case.
+ - When you call `FirebaseAnalytics.LogAppleTransactionAsync(transactionId)` with the simulated transaction ID:
+ - It should log the transaction to the console. Both the Xcode console and firebase console should show a log for an in app purchase.
+
## Troubleshooting
diff --git a/docs/readme.md b/docs/readme.md
index df422861..37584167 100644
--- a/docs/readme.md
+++ b/docs/readme.md
@@ -109,6 +109,12 @@ Support
Release Notes
-------------
+### Upcoming
+- Changes
+ - Analytics: Add support for Apple's Store kit 2 transactions. Add new `LogAppleTransactionAsync` method
+ that takes in the App Store transaction string and logs the transaction.
+
+
### 13.11.0
- Changes
- General: Update to Firebase C++ SDK version 13.7.0.