didomi / react-native

Didomi SDK for React Native
Other
9 stars 2 forks source link

getEnabledVendorIds is not updated after user changes consent during showPreferences #41

Open Minishlink opened 2 years ago

Minishlink commented 2 years ago

Step 1 : install a fresh app Step 2 : accept all cookies => getEnabledVendorIds contains everything Step 3 : showPreferences Step 4 : refuse all cookies => getEnabledVendors still contains everything instead of nothing

Not tested on Android

Minishlink commented 2 years ago

A workaround is using getUserStatus (.vendors.global.enabled)

EDIT: apparently this doesn't always work on iOS

Minishlink commented 2 years ago

Workaround doesn't work on Android (a workaround for this is to call Didomi.reset before showPreferences, but then the user doesn't see its previous enabled/disabled cookies and you can dismiss the showPreferences without setting any preference)

felipe-saez commented 2 years ago

Hello Louis,

Apologies for not replying earlier. The getEnabledVendors has been deprecated. Please use the getUserStatus method instead https://developers.didomi.io/cmp/mobile-sdk/react-native/reference#getuserstatus.

If what you need is to check if the user has enabled all Legitimate Interest and Consent purposes linked to vendors, then you might want to use vendors.global.enabled. This should work on both iOS and Android.

The reset method should be used mostly for testing.

I hope this helps.

Kind regards,

Felipe

Minishlink commented 2 years ago

Hello Felipe,

Thanks for your answer. If getEnabledVendors is deprecated, it should be noted as such in the typescript definitions ;) Anyway, I'm using getUserStatus now with vendors.global.enabled, and I do need to call reset before showPreferences, otherwise getUserStatus doesn't update after CONSENT_CHANGED.

const handleConsents = async () => {
  const userStatus = await Didomi.getUserStatus();
  const enabledVendors = userStatus.vendors.global.enabled; // https://github.com/didomi/react-native/issues/41
  // here I use enabledVendors to configure SDKs
};

export const useGDPRConsent = () => {
  const [isConsenting, setIsConsenting] = useState(true);

  useEffect(() => {
    Didomi.onReady()
      .then(async () => {
        await Didomi.setupUI();

        if (!(await Didomi.shouldConsentBeCollected())) {
          await handleConsents();
          setIsConsenting(false);
        }
      })
      .catch(error => {
        setIsConsenting(false);
        handleError({
          record: {
            error,
            context: 'Didomi ready',
          },
        });
      });

    Didomi.onError().then(error => {
      setIsConsenting(false);
      handleError({
        record: {
          error:
            error instanceof Error
              ? error
              : new Error(typeof error === 'string' ? error : JSON.stringify(error)),
          context: 'Didomi initialization',
        },
      });
    });

    Didomi.addEventListener(DidomiEventType.CONSENT_CHANGED, async () => {
      try {
        await handleConsents();
      } catch (error) {
        handleError({
          record: {
            error,
            context: 'Didomi consent change',
          },
        });
      } finally {
        setIsConsenting(false);
      }
    });

    Didomi.initialize(env.DIDOMI_API_KEY);

    return () => {
      Didomi.removeAllEventListeners();
    };
  }, []);

  return {
    isConsenting,
  };
};

And the on press callback on the button to manage cookies:

const showCookieConsentSettings = useCallback(async () => {
    await Didomi.reset(); // https://github.com/didomi/react-native/issues/41
    return Didomi.showPreferences();
  }, []);
pmerlet-at-didomi commented 2 years ago

Hello, you are correct about the deprecated method, it seems we forgot to deprecate some of the status methods in typescript. This will be fixed in the next release. Your code should work using the getUserStatus method. Can you be more specific with the problem you encounter on iOS? I was not able to reproduce it, getUserStatus returns the updated result when called after CONSENT_CHANGED event is received. As you mentioned, by resetting consents before calling showPreferences, the user is not able to see its previous choice, and there will be no consent if preferences screen is dismissed.

Minishlink commented 2 years ago

I reproduced it today too after having updated the SDK, on Android but not on iOS. (although this doesn't mean anything since it looks like a race condition) One info worth noting is that by calling showPreferences, accepting/refusing, multiple times, at one point the CONSENT_CHANGED didn't trigger anymore, and then after trying again, it fired 4 CONSENT_CHANGED at once.