-
-
Notifications
You must be signed in to change notification settings - Fork 227
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Build] Separate firebase-enabled and non-firebase builds #143
Comments
what about calling firebase through api, I think it has RESTFull API we can use instead of adding the library itself. As example |
It seems the api is for the db not app check? The app is using fb for the App Check. |
I was just about to ask about the sudden web traffic I saw coming from the appstore app, as soon as it launched, that wasn't there before. |
Yeah, I don’t like being dependent on Google services, but I don’t have many options for allowing folks to share their benchmarks for this: https://huggingface.co/spaces/a-ghorbani/ai-phone-leaderboard. I am just a single dev :) If anyone has an alternative that doesn’t require using Firebase App Check for this, I’d be happy to explore it. By the way, what tool do you use for monitoring network traffic? |
Is it possible to make it only connect to firebase when an attempt to share a Benchmark occurs? For looking at traffic, I use a combination of things and always switching them around, but currently:
Also, I tend to proxy iphone through stuff like Fiddler (Classic) |
btw, I don't know about coding on iOS, but I used an LLM for ideas. Does this make any sense or seem feasible? Analyzing the Current ImplementationYour current Step-by-Step Modification of AppDelegate.mm
First, let's create a new Objective-C class called Create a new file named // FirebaseManager.h
#import <Foundation/Foundation.h>
@interface FirebaseManager : NSObject
+ (instancetype)sharedInstance;
- (void)configureFirebaseIfNeeded;
@end Now create // FirebaseManager.m
#import "FirebaseManager.h"
#import <Firebase.h>
#import "RNFBAppCheckModule.h"
@implementation FirebaseManager
static FirebaseManager *sharedInstance = nil;
static dispatch_once_t onceToken;
+ (instancetype)sharedInstance {
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
- (void)configureFirebaseIfNeeded {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[RNFBAppCheckModule sharedInstance];
[FIRApp configure];
NSLog(@"Firebase configured");
});
}
@end
Now, let's update your #import "AppDelegate.h"
#import "FirebaseManager.h"
#import <React/RCTBundleURLProvider.h>
#import <RNFSBackgroundDownloads.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Remove Firebase initialization from here
self.moduleName = @"PocketPal";
self.initialProps = @{};
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
// ... (rest of your AppDelegate implementation)
@end
To allow your React Native code to trigger Firebase initialization when needed, create a native module: Create a new file named // RNFirebaseManager.h
#import <React/RCTBridgeModule.h>
@interface RNFirebaseManager : NSObject <RCTBridgeModule>
@end Now create // RNFirebaseManager.m
#import "RNFirebaseManager.h"
#import "FirebaseManager.h"
@implementation RNFirebaseManager
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(configureFirebase)
{
[[FirebaseManager sharedInstance] configureFirebaseIfNeeded];
}
@end
In your React Native JavaScript code, you can now control when Firebase is initialized: import { NativeModules } from 'react-native';
const { RNFirebaseManager } = NativeModules;
// Call this when you need Firebase
function initializeFirebaseIfNeeded() {
RNFirebaseManager.configureFirebase();
}
// Use this function before any Firebase-dependent operations Explanation of Changes
Best Practices and Considerations
By implementing these changes, your app will no longer automatically connect to |
Then I tried Copilot's Output: To stop the app from reaching out to
Here are the relevant code snippets:
import '@react-native-firebase/app-check';
import firebase from '@react-native-firebase/app';
import { APPCHECK_DEBUG_TOKEN_ANDROID, APPCHECK_DEBUG_TOKEN_IOS } from '@env';
let isAppCheckInitialized = false;
export const initializeAppCheck = () => {
if (isAppCheckInitialized) {
return;
}
try {
const rnfbProvider = firebase
.appCheck()
.newReactNativeFirebaseAppCheckProvider();
rnfbProvider.configure({
android: {
provider: __DEV__ ? 'debug' : 'playIntegrity',
debugToken: APPCHECK_DEBUG_TOKEN_ANDROID,
},
apple: {
provider: __DEV__ ? 'debug' : 'appAttestWithDeviceCheckFallback',
debugToken: APPCHECK_DEBUG_TOKEN_IOS,
},
});
firebase.appCheck().initializeAppCheck({
provider: rnfbProvider,
isTokenAutoRefreshEnabled: true,
});
isAppCheckInitialized = true;
} catch (error) {
console.error('Failed to initialize Firebase App Check:', error);
}
};
export const getAppCheckToken = async () => {
try {
if (!firebase.appCheck) {
throw new Error('Firebase App Check module is not available');
}
const { token } = await firebase.appCheck().getToken(true);
return token;
} catch (error) {
console.error('Failed to get App Check token:', error);
throw error;
}
};
import axios from 'axios';
import { urls } from '../config';
import { getAppCheckToken, initializeAppCheck } from '../utils/fb';
import { BenchmarkResult, DeviceInfo } from '../utils/types';
type SubmissionData = {
deviceInfo: DeviceInfo;
benchmarkResult: BenchmarkResult;
};
export async function submitBenchmark(
deviceInfo: DeviceInfo,
benchmarkResult: BenchmarkResult,
): Promise<{ message: string; id: number }> {
try {
// Initialize App Check here
initializeAppCheck();
const appCheckToken = await getAppCheckToken();
if (!appCheckToken) {
throw new Error('Failed to obtain App Check token');
}
const data: SubmissionData = {
deviceInfo,
benchmarkResult,
};
const response = await axios.post(urls.benchmarkSubmit(), data, {
headers: {
'X-Firebase-AppCheck': appCheckToken,
'Content-Type': 'application/json',
},
});
return response.data;
} catch (error) {
console.error('Error submitting benchmark:', error);
if (error instanceof Error) {
console.error('Error details:', error.message);
}
throw error;
}
}
const handleShareResult = async (result: BenchmarkResult) => {
if (!deviceInfo) {
throw new Error('Device information not available');
}
if (result.submitted) {
throw new Error('This benchmark has already been submitted');
}
try {
// Initialize App Check here
initializeAppCheck();
const response = await submitBenchmark(deviceInfo, result);
console.log('Benchmark submitted successfully:', response);
benchmarkStore.markAsSubmitted(result.uuid);
} catch (error) {
console.error('Failed to submit benchmark:', error);
throw error;
}
}; By following these steps, you can ensure that the Firebase App Check is only performed when the Benchmark feature is used. For more details, you can view the search results. |
@a-ghorbani ...thoughts? |
@TFWol This is very helpful. Thanks for digging into this. by the looks of it, it seems like it should work. and will make it easier to create separate builds too. I'll be divin into this, but need a bit time. |
Issue description
Currently the app only needs Firebase (App Check) for one specific feature: sharing benchmark results with the community. We use App Check to verify the legitimacy of these benchmark submissions (i.e., to ensure they come from real users rather than automated scripts, etc). For custom compiles or other platforms like fdroid we can disable sharing benchmarks, so Firebase is unnecessary.
Therefore, we want to provide two distinct build variants/flavors:
Potential solution:
Android
android/app/build.gradle
:firebaseEnabled
flavor:google-services.json
and apply the Google Services plugin.firebaseDisabled
flavor:google-services.json
.iOS
FirebaseEnabled
target referencesGoogleService-Info.plist
.FirebaseDisabled
target does not include any Firebase refs.Podfile
depending on build configs.ts code
@react-native-firebase
modules (e.g.,app
,app-check
)The text was updated successfully, but these errors were encountered: