Shopify / ui-extensions

MIT License
266 stars 36 forks source link

useCustomer hook not updating on email change #2034

Open charlesLoder opened 4 months ago

charlesLoder commented 4 months ago

Please list the package(s) involved in the issue, and include the version you are using

"dependencies": {
    "react": "^18.0.0",
    "@shopify/ui-extensions": "2024.1.x",
    "@shopify/ui-extensions-react": "2024.1.x"
  },
  "devDependencies": {
    "@types/react": "^18.0.0",
    "react-reconciler": "0.29.0"
  }

Describe the bug

See more context in forums

According to the documentation for the useCustomer hook, it:

Returns the current Customer. The value is undefined if the buyer isn't a known customer for this shop or if they haven't logged in yet.

which indicates that there are two conditions in which the hook may return a customer — when they are "known" or "logged in". The second condition is clear, but the first is not.

Steps to reproduce the behavior:

See minimal example:

import {
  useCustomer,
  TextBlock,
  reactExtension,
} from "@shopify/ui-extensions-react/checkout";

export default reactExtension("purchase.checkout.contact.render-after", () => (
  <Extension />
));

function Extension() {
  const customer = useCustomer();

  if (!customer) {
    return <TextBlock>You're not a customer</TextBlock>;
  }

  return <TextBlock>You're a customer</TextBlock>;
}

Expected behavior

I expected when the email field is updated (i.e. a "known customer"), that the customer/buyer identity would as well, similar to a purchase validation function:

/**
 * @param {RunInput} input
 * @returns {FunctionRunResult}
 */
export function run(input) {
  const errors = [];
  const customerTags = input.cart.buyerIdentity?.customer?.hasTags;
  const cartLines = input.cart?.lines;

  const hasSample = cartLines.find(line => line.merchandise?.product?.handle == "sample");

  if(!hasSample){
    return {
      errors
    }
  }

  if(input.cart.buyerIdentity != null && input.cart.buyerIdentity?.customer != null){
    if(hasTag(customerTags, "sample")) {
      errors.push({
        localizedMessage: "Only 1 sample is allowed per customer.",
        target: "cart",
      });   
    }
  }

  return {
    errors
  }
};

Additional context

charlesLoder commented 3 months ago

Following up. Any thoughts?

jamesvidler commented 3 months ago

Yes, it looks like our description is a little misleading. You are only able to retrieve the customer details if the customer is logged with a customer account, or they are in a Shop Pay checkout (where UI extensions also run). We'll look to update that.

Regarding your use case, you might want to consider using fetch from the UI extension to an app backend which would then take the email address and query the Admin API to find a corresponding customer (and their tags).

charlesLoder commented 3 months ago

@jamesvidler

Thanks for the reply. We don't have a full backend (extensions only), so fetch won't be possible.

If I'm inferring correctly that "known customer" = using Shop Pay, then some updates to the documentation would be much appreciated.