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

Migration guide: @awesome-cordova-plugins to @revenuecat/capacitor-purchases [docs] #108

Open
mepc36 opened this issue Sep 14, 2023 · 7 comments

Comments

@mepc36
Copy link

mepc36 commented Sep 14, 2023

Hi, how do I solve an error message that says "Missing identifier parameter in {}"?

Here is how I'm initializing purchases in a hook:

export function usePurchases() {
  const [isPurchasesInitialized, setIsInitialized] = useState(false)

  useEffect(() => {
    (async () => {
      const { Purchases, LOG_LEVEL } = (await import('@revenuecat/purchases-capacitor'))

      if (!isPurchasesInitialized) {
        const userUuid = await getUserUuid()
        Purchases.setLogLevel({ level: LOG_LEVEL.DEBUG });
        const apiKey = Capacitor.getPlatform() === 'android' ?
          process.env.REVENUECAT_API_KEY_ANDROID :
          process.env.REVENUECAT_API_KEY_IOS

        Purchases.configure({
          apiKey,
          appUserID: userUuid
        });
        myPurchases = Purchases

        setIsInitialized(true)
      }
    })()
  }, [isPurchasesInitialized]);

  return { isPurchasesInitialized, Purchases: myPurchases };
}

This is how I get and set the purchases' offerings and customer Info:

          const offerings = await Purchases.getOfferings();
          setOfferings(offerings)
          const customerInfo = process.env.APP_ENVIRONMENT === 'development' && SUBSCRIBE_DEV_USERS ?
            DEV_CUSTOMER_INFO :
            await Purchases.getCustomerInfo()

Here is the code that runs when the "Purchase Package" button is clicked:

console.log(offeringPackage)
await Purchases.purchasePackage(offeringPackage);

Here is what the offeringPackage log in the above code prints:

{
    "identifier": "$rc_monthly",
    "packageType": "MONTHLY",
    "product": {
        "identifier": "xxxxxx",
        "description": "Gives access to pro features of the RapBot app.",
        "title": "Pro (RapWriter)",
        "price": 0.99,
        "priceString": "$0.99",
        "currencyCode": "USD",
        "introPrice": null,
        "discounts": null,
        "productCategory": "SUBSCRIPTION",
        "productType": "AUTO_RENEWABLE_SUBSCRIPTION",
        "subscriptionPeriod": "P1M",
        "defaultOption": {
            "id": "xxxxx",
            "storeProductId": "xxxxx:xxxxx",
            "productId": "xxxxx",
            "pricingPhases": [
                {
                    "billingPeriod": {
                        "unit": "MONTH",
                        "value": 1,
                        "iso8601": "P1M"
                    },
                    "recurrenceMode": 1,
                    "billingCycleCount": 0,
                    "price": {
                        "formatted": "$0.99",
                        "amountMicros": 990000,
                        "currencyCode": "USD"
                    },
                    "offerPaymentMode": null
                }
            ],
            "tags": [],
            "isBasePlan": true,
            "billingPeriod": {
                "unit": "MONTH",
                "value": 1,
                "iso8601": "P1M"
            },
            "isPrepaid": false,
            "fullPricePhase": {
                "billingPeriod": {
                    "unit": "MONTH",
                    "value": 1,
                    "iso8601": "P1M"
                },
                "recurrenceMode": 1,
                "billingCycleCount": 0,
                "price": {
                    "formatted": "$0.99",
                    "amountMicros": 990000,
                    "currencyCode": "USD"
                },
                "offerPaymentMode": null
            },
            "freePhase": null,
            "introPhase": null,
            "presentedOfferingIdentifier": "xxxxxx"
        },
        "subscriptionOptions": [
            {
                "id": "xxxxx",
                "storeProductId": "xxxx:xxxx",
                "productId": "xxxx",
                "pricingPhases": [
                    {
                        "billingPeriod": {
                            "unit": "MONTH",
                            "value": 1,
                            "iso8601": "P1M"
                        },
                        "recurrenceMode": 1,
                        "billingCycleCount": 0,
                        "price": {
                            "formatted": "$0.99",
                            "amountMicros": 990000,
                            "currencyCode": "USD"
                        },
                        "offerPaymentMode": null
                    }
                ],
                "tags": [],
                "isBasePlan": true,
                "billingPeriod": {
                    "unit": "MONTH",
                    "value": 1,
                    "iso8601": "P1M"
                },
                "isPrepaid": false,
                "fullPricePhase": {
                    "billingPeriod": {
                        "unit": "MONTH",
                        "value": 1,
                        "iso8601": "P1M"
                    },
                    "recurrenceMode": 1,
                    "billingCycleCount": 0,
                    "price": {
                        "formatted": "$0.99",
                        "amountMicros": 990000,
                        "currencyCode": "USD"
                    },
                    "offerPaymentMode": null
                },
                "freePhase": null,
                "introPhase": null,
                "presentedOfferingIdentifier": "xxxx"
            }
        ],
        "presentedOfferingIdentifier": "xxxx"
    },
    "offeringIdentifier": "xxxx"
}

What am I doing wrong?

Thanks for the plugin!

@mepc36
Copy link
Author

mepc36 commented Sep 14, 2023

Looks like the package you're purchasing needs to be passed at a property inside an options object like so:

await Purchases.purchasePackage({ aPackage: offeringPackage });

@mepc36 mepc36 closed this as completed Sep 14, 2023
@mepc36
Copy link
Author

mepc36 commented Sep 14, 2023

As one more note:

this code/thread will be particularly helpful for anyone migrating from @awesome-cordova-plugins/purchases to this package. This new package is mainly a drop-in replacement, with the following changes:

  1. Don't call Purchases.configureWith, but instead call Purchases.configure
  2. This aforementioned .purchasePackage problem detailed above.
  3. .restorePurchases() does work the same
  4. Don't call Purchases.setDebugLogs, but Purchases.setLogLevel({ level: LOG_LEVEL.DEBUG }) instead.
  5. customerInfo is now nested inside a larger returned object, so instead of this...
          const customerInfo = await Purchases.getCustomerInfo()

...call this:

          const { customerInfo } = await Purchases.getCustomerInfo()

If I run into any other problems, I will report back. Thanks!

@mepc36 mepc36 changed the title Missing identifier parameter in {} Migration guide: @awesome-cordova-plugins to @revenuecat/capacitor-purchases [docs] Sep 14, 2023
@mepc36 mepc36 reopened this Sep 14, 2023
@mepc36
Copy link
Author

mepc36 commented Sep 14, 2023

Leaving open for visibility, maintainers, feel free to close if you don't think a meaningful subset of your users will want this!

@Martijn0405
Copy link

Martijn0405 commented Sep 20, 2023

@mepc36 Hi! I had a question about the migration.

I am using this code on a NextJS project:
import { Purchases } from "@revenuecat/purchases-capacitor"

await Purchases.configure({
apiKey,
appUserID: uid
})

But getting this error:
Error: "CapacitorPurchases" plugin is not implemented on android

Do you maybe have any idea why it is not using Purchases instead of CapacitorPurchases?

When using:
import { CapacitorPurchases } from '@capgo/capacitor-purchases';

CapacitorPurchases.setDebugLogsEnabled({ enabled: true }).then()

The app crashes instrantly, what would be a correct and functioning code solution at this moment?

@aboedo
Copy link
Member

aboedo commented Oct 6, 2023

@mepc36 thanks for sharing! Sorry for the delayed response, not sure how we missed this. @codykerns @tonidero we should have a section of the docs dedicated to this specific migration, I think @mepc36 is right and it'll be a common use case.

@Martijn0405 I'd recommend performing a clean install:

  • remove the SDK
  • reinstall the SDK through npm install @revenuecat/purchases-capacitor
  • run ionic cap sync and then ionic cap run android

@tonidero
Copy link
Contributor

tonidero commented Oct 8, 2023

Oh sorry we missed this! We have this doc with the changes in the API: https://github.com/RevenueCat/purchases-capacitor/blob/main/migrations/v6-MIGRATION.md, but we can add a link to that in the docs. Also, I think we might be able to explain a bit more about the changes in the doc

@tonidero
Copy link
Contributor

tonidero commented Oct 8, 2023

One question @mepc36, about this point:

customerInfo is now nested inside a larger returned object, so instead of this...

     const customerInfo = await Purchases.getCustomerInfo()

...call this:

     const { customerInfo } = await Purchases.getCustomerInfo()

If I run into any other problems, I will report back. Thanks!

This seems like it didn't change from version 5.x of the plugin. Did you update from an older version of the plugin?

Edit: Sorry, please ignore the above, you did mention you're coming from @awesome-cordova-plugins. As Andy said, we are planning to create a guide to migrate from that to this plugin. Sorry for the noise!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants