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

bug: Android build variables are replaced during sync #3026

Closed
1 of 4 tasks
robingenz opened this issue Jun 1, 2020 · 9 comments · Fixed by #3030
Closed
1 of 4 tasks

bug: Android build variables are replaced during sync #3026

robingenz opened this issue Jun 1, 2020 · 9 comments · Fixed by #3030

Comments

@robingenz
Copy link
Contributor

robingenz commented Jun 1, 2020

Bug Report

My Android project has several product flavors. Each product flavor has a different applicationId.
I need build variables to set the correct values in the android manifest. Unfortunately these build variables are replaced by static values during sync.

Affected Platform(s)

  • Android
  • iOS
  • Electron
  • Web

Current Behavior

During ionic capacitor sync ancdroid, Android build variables are replaced by static values.

Example:
My android project has two flavors: io.ionic.first and io.ionic.second.
android/app/src/main/AndroidManifest.xmlcontains these lines:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="io.ionic.first">
    ...
    <uses-permission android:name="${applicationId}.permission.RECEIVE_ADM_MESSAGE" />
</manifest>

android/app/build.gradle contains these lines:

productFlavors {
        FIRST {
            dimension = 'asset'
            applicationId = 'io.ionic.first'
        }
        SECOND {
            dimension = 'asset'
            applicationId = 'io.ionic.second'
        }
}

After ionic capacitor sync android the file android/capacitor-cordova-android-plugins/src/main/AndroidManifest.xml looks like this:

<?xml version='1.0' encoding='utf-8'?>
<manifest package="capacitor.android.plugins"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:amazon="http://schemas.amazon.com/apk/res/android">
...
<uses-permission android:name="io.ionic.first.permission.RECEIVE_ADM_MESSAGE"/>
<permission android:name="io.ionic.first.permission.RECEIVE_ADM_MESSAGE" android:protectionLevel="signature"/>
</manifest>

${applicationId} was replaced by io.ionic.first.
This means that if I now build an app with the application id io.ionic.second, it contains the permission io.ionic.first.permission.RECEIVE_ADM_MESSAGE.
But this should not be the case, because it can lead to conflicts between the apps.
For example:

$ adb install android/app/build/outputs/apk/AMS/debug/app-SECOND-debug.apk

Performing Streamed Install
adb: failed to install android/app/build/outputs/apk/SECOND/debug/app-SECOND-debug.apk: Failure [INSTALL_FAILED_DUPLICATE_PERMISSION: Package io.ionic.second attempting to redeclare permission io.ionic.first.permission.RECEIVE_ADM_MESSAGE already owned by io.ionic.first]

Capacitor Version

npx cap doctor output:

💊   Capacitor Doctor  💊 

Latest Dependencies:

  @capacitor/cli: 2.1.2

  @capacitor/core: 2.1.2

  @capacitor/android: 2.1.2

  @capacitor/electron: 2.1.2

  @capacitor/ios: 2.1.2

Installed Dependencies:

  @capacitor/ios not installed

  @capacitor/electron not installed


  @capacitor/cli 2.1.2

  @capacitor/android 2.1.2

  @capacitor/core 2.1.2

[success] Android looking great! 👌

Expected Behavior

After ionic capacitor sync android the file android/capacitor-cordova-android-plugins/src/main/AndroidManifest.xml should contain the following lines:

<?xml version='1.0' encoding='utf-8'?>
<manifest package="capacitor.android.plugins"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:amazon="http://schemas.amazon.com/apk/res/android">
...
<uses-permission android:name="${applicationId}.permission.RECEIVE_ADM_MESSAGE"/>
<permission android:name="${applicationId}.permission.RECEIVE_ADM_MESSAGE" android:protectionLevel="signature"/>
</manifest>

Sample Code or Sample Application Repo

Reproduction Steps

  1. Create blank ionic capacitor project
  2. npx ionic build
  3. Add a cordova plugin that requires a placeholder in the AndroidManifest.xml, for exmaple OneSignal(https://documentation.onesignal.com/docs/ionic-sdk-setup).
  4. npx ionic capacitor sync android

Other Technical Details

npm --version output: 6.14.5

node --version output: v13.12.0

Other Information

@jcesarmobile
Copy link
Member

can you provide a sample app?

@jcesarmobile jcesarmobile added the needs reply needs reply from the user label Jun 1, 2020
@robingenz
Copy link
Contributor Author

robingenz commented Jun 1, 2020

Sure, there is an example project: https://github.com/robingenz/capacitor-issue-3026-example

This example project does NOT include several product flavors.
They are not necessary for the bug.
The bug only affects them and occurs anyway.

Required steps:

  1. git clone https://github.com/robingenz/capacitor-issue-3026-example.git
  2. cd capacitor-issue-3026-example && npm i
  3. npx ionic capacitor sync android
<uses-permission android:name="${applicationId}.permission.RECEIVE_ADM_MESSAGE" />

in android/app/src/main/AndroidManifest.xml becomes

<uses-permission android:name="io.ionic.starter.permission.RECEIVE_ADM_MESSAGE"/>
<permission android:name="io.ionic.starter.permission.RECEIVE_ADM_MESSAGE" android:protectionLevel="signature"/>

in android/capacitor-cordova-android-plugins/src/main/AndroidManifest.xml.

@jcesarmobile
Copy link
Member

onesignal plugin has the permission declared as <uses-permission android:name="$PACKAGE_NAME.permission.RECEIVE_ADM_MESSAGE" />

capacitor CLI replaces $PACKAGE_NAME with the appId configured in capacitor.config.json
as far as I remember it was because $PACKAGE_NAME caused problems, but we can probably change the replace to ${applicationId}.
or onesignal could also update their plugin.xml to use ${applicationId} instead of $PACKAGE_NAME

@jcesarmobile jcesarmobile removed the needs reply needs reply from the user label Jun 1, 2020
@robingenz
Copy link
Contributor Author

Okay, now I understand the problem.
Thanks for pointing that out.

In my opinion, an adjustment to the Capacitor CLI is recommended here.
Replacing $PACKAGE_NAME with the appId in capacitor.config.json is a working solution, but it prevents the use of Capacitor (or the use of certain Cordova plugins in Capacitor) in the scenario described above.
Certainly, replacing $PACKAGE_NAME with $applicationId in OneSignal could be a solution.
However, the problem could still occur with other plug-ins.
In addition, $PACKAGE_NAME is a variable that is also used in the official Cordova plugin documentation and should therefore be supported as widely as possible by Capacitor.

From the Cordova documentation:

Certain variable names should be reserved, like $PACKAGE_NAME. This is the reverse-domain style unique identifier for the package, corresponding to the CFBundleIdentifier on iOS or the package attribute of the top-level manifest element in an AndroidManifest.xml file.

So $PACKAGE_NAME does indeed represent the $applicationId.

@robingenz
Copy link
Contributor Author

I've created a PR for this: #3030

@robingenz
Copy link
Contributor Author

Are there any open questions or can I still help in any way?

@timo-haas
Copy link

I am facing the same issue. Are there any outstanding tasks?

@jcesarmobile
Copy link
Member

So $PACKAGE_NAME does indeed represent the $applicationId.

No, $PACKAGE_NAME and $applicationId are different things, if you add product flavors in a cordova app you'll face the same issue you are facing with Capacitor, because at the moment Capacitor behaves the same way as cordova. Cordova replaces the $PACKAGE_NAME with the value of the id field in config.xml, Capacitor with the value of appId in capacitor.config.json.
When you add product flavors the package name and the application id differ, happens on both Cordova and Capacitor.

I'll add your changes as I think it makes more sense to use the $applicationId instead of the package name, at least for one signal plugin, but it might cause problems with other plugins that really want the package name, if that happens I'll revert and find another solution.
Will also send a PR to one signal plugin so it uses $applicationId

@ionitron-bot
Copy link

ionitron-bot bot commented Nov 11, 2022

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Capacitor, please create a new issue and ensure the template is fully filled out.

@ionitron-bot ionitron-bot bot locked and limited conversation to collaborators Nov 11, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants