Skip to content
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

[Discussion] Alternative to app.json based configuration #596

Closed
DoctorJohn opened this issue Jul 1, 2024 · 6 comments · Fixed by #602
Closed

[Discussion] Alternative to app.json based configuration #596

DoctorJohn opened this issue Jul 1, 2024 · 6 comments · Fixed by #602
Labels
help wanted Extra attention is needed released

Comments

@DoctorJohn
Copy link
Contributor

DoctorJohn commented Jul 1, 2024

Hi everyone,

I feel like this might be an unpopular proposal, but I want to discuss replacing the app.json-based configuration approach with a more standard React Native way.

Specifically, I propose:

  • letting bare React Native users configure their app by manually updating AndroidManifest.xm and Info.plist. This feels pretty natural to me because I already have to do this with various other React Native packages. It's also well document in the upstream Google Mobile Ads documentation for iOS and Android.
  • adding a Expo config plugin for the surge of Expo users. Usually Expo users understand that packages which require config plugins are not compatible with Expo Go, so they'll hopefully stop asking why their apps are crashing.

And here is why:

  • This package is getting more and more Expo users who request/expect app.config.js and app.config.ts support. However, working with the js/ts files in this context is not trivial¹ and may require executing these files in an appropriate runtime environment
  • Maintaining ios_config.sh feels already hard enough and PRs touching them tent to take much longer to get merged
  • Expo SDK 51 started urging users² to move any non-expo top level field from the app.json file under an extra object, which will like require us to handle yet another case³
  • Bare React Native users are already used to managing their AndroidManifest.xm and Info.plist files and personally I feel like that's the natural way of doing it
  • A config plugin signals to Expo users that Expo Go is not supported which could reduce the amount of newly created issues around that topic

Closing thoughts:

Many of these points mention Expo because we get many reports⁴ from Expo users and now that Expo is the officially recommended React Native framework⁴, I feel like they'll keep coming.

What are your thoughts on this @mikehardy and @dylancom? Feel free to argue against it, this is supposed to be a discussion. Personally I'm not necessarily unhappy with the current approach I just feel like this proposal could be more sustainable, simpler, more standardized and comes with some benefits. Oh, in case it's not obvious: I'll happily implement all these changes.

References:

¹: for example see: #521
²: https://expo.fyi/root-expo-object
³: related PR: #584
⁴: active issue on app.json related expo config issues : #581
⁵: https://reactnative.dev/blog/2024/06/25/use-a-framework-to-build-react-native-apps

@DoctorJohn DoctorJohn added the help wanted Extra attention is needed label Jul 1, 2024
@dylancom
Copy link
Collaborator

dylancom commented Jul 4, 2024

Hi @DoctorJohn, both proposals sound good to me.
I myself (and other bare users) are used to adjusting the Info.plist in bare React Native projects.
The ios_config.sh came from a time when Expo wasn't that popular yet (and from the prev firebase lib 3 years ago).
There have been several PR's adjusting the config but most of them seem to also break things for other users.
It's hard to maintain and should be simpler.
I have also tried to tag @mikehardy in those PR's to see what his thoughts are (as he is a more expert in this field).

Since Expo is now being recommended the issues will rise even more and making it compatible by default would benefit us all in the end. Would be great if we could reduce the issues reported by Expo Go users as I have been getting pretty tired seeing those...

I am back from holiday so I'll happily review those (breaking) changes.
Thanks for bringing this up and great your willing to implement it.

@mikehardy
Copy link
Collaborator

I'm willing to continue maintenance on the automated ios_config script, I find it helpful, though I recognize many are familiar with it, those scripts exist because user support is reduced.

I like all the rest of the line if thinking, just hope there is a way to keep the native assist for bare users. Perhaps a check to see if it's configured in the "new way" whatever that is (config plugin sounds great, moving things where Expo wants them sounds useful...) then if it's the new way skip it otherwise assume it's bare mode and configure that way?

I may be talking nonsense and that's not possible but I can't imagine how much more non expo support we'd have here and in firebase if native file manipulation was mandatory...

@dylancom
Copy link
Collaborator

dylancom commented Jul 4, 2024

Good idea @mikehardy. I think we can adjust ios_config.sh to early exit if app.json contains a react-native-google-mobile-ads (expo config) plugin?

@DoctorJohn
Copy link
Contributor Author

DoctorJohn commented Jul 4, 2024

Thanks for the feedback to both of you!

Regarding offering config plugin and the current approach:

We could theoretically keep the ios_config.js and the corresponding code in build.gradle, but getting the "early exit" condition right needs some consideration. Here are some thoughts:

  • Expo projects can choose to use either or both app.config.*s and app.json. From my experience, many Expo projects add an app.config.*s at some point for dynamic configuration of some kind (e.g. to configure flavor-specific settings such as API URLs, app name, app icon or even Ad Unit IDs). Checking for the config plugins in app.json alone would not be sufficient.
  • That's where detecting the config plugin gets complicated (even impossible from a theoretical standpoint for those who are familiar with the halting problem): It's essentially impossible to detect whether a project only using app.config.*s has the conflig plugin configured or not.
  • Requiring users to always keep an app.json file brings us back to one point raise in the first post: the react-native-google-mobile-ads key would have to be moved for expo projects. Technically that's not a problem, but yet another setup variant we have to wrap our heads around when new issues come in.

Given the argumentation above I would recommend against checking for the usage of the config plugin itself and instead check whether the expo package is listed in the package.json file.
Expo modules can be installed in bare RN projects too in which case they also have the expo package installed, but if feel like a this point they should use the config plugin too.

Regarding the assistance of bare RN users:

I feel like those users are more competent than ever given that the RN website has been directing newcomers to Expo for at least a few years now. IMHO the amount of issues raised by those users regarding touching native files should be low(?) but I lean towards trusting Mikes judgement on this given how many issues he's triaging in various repositories.

That being said: Our ios_config.sh/build.gradle solution does basically the same as a config plugin and config plugins can technically be used by bare RN projects too. They only need to depend on the slim expo package, add the config plugin as usual and run npx expo prebuild to update their native code before building.

All I'm trying to say with the last part is: we don't necessarily have to maintain our custom ios_config.sh/build.gradle solution to offer an option for bare users that does not involve manually touching native files. I feel like bare RN users nowadays know what they signed up for and might be more confused by our custom solution than by manually touching native files. But that's just my personal opinion, if in doubt trust Mike's.

I'll start working on the config plugin for now :)

@dylancom dylancom pinned this issue Jul 9, 2024
@DoctorJohn
Copy link
Contributor Author

Update: So far I have a working config plugin, tests and I made ios_config.sh exit early if expo is detected.

Now I'm stuck with build.gradle in manifest merging hell because this library's meta-data tags conflict with the ones added by the config plugin. I tried to let build.gradle only conditionally include these meta-data tags, but that doesn't seem to be possible without product flavors (which I don't think can be utilized by RN libraries?). I will now try to update the config plugin to include merge rule markers which will cause the meta-data tags added by the config plugin to overwrite the ones added by the library's AndroidManifest.xml.

@mikehardy
Copy link
Collaborator

🎉 This issue has been resolved in version 14.0.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@dylancom dylancom unpinned this issue Jul 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed released
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants