Mudasser
Mudasser

Reputation: 315

"There’s no page at this address" error on Shopify Embedded App installation

I am facing a strange issue, When I install app first time on test store, installation goes smooth but after re-installation after OAuth, Shopify show me "There’s no page at this address" error.

My app submission was rejected due to this reason. I am using https://github.com/osiset/laravel-shopify library.

This is image of error.

Upvotes: 5

Views: 7686

Answers (10)

Mohit Verma
Mohit Verma

Reputation: 1

I have faced the same problem with Ruby on Rails application. So I set config.new_embedded_auth_strategy to false. It worked for me.

Upvotes: 0

Mohit Nandpal
Mohit Nandpal

Reputation: 143

In Laravel, When we install any app from the shopify app store, It'll create a new store in our user table. If you are using an Osiset/Laravel or ohmybrew/laravel-Shopify package then you have to delete your store first from your database or create a new webhook to enable uninstall functionality using this below code.

Add this code to your .env file

SHOPIFY_UNINSTALLED=APP_UNINSTALLED
SHOPIFY_UNINSTALLED_ADDRESS=yourdomain.com/webhook/app-uninstalled

This webhooks is used to uninstall your app from store and delete your store's entry from database.

Upvotes: 0

John Wedgbury
John Wedgbury

Reputation: 181

The accepted answer did not work for us. We resolved this another way.

We found that the /web/public directory in the boilerplate (after running npm run build) contained BOTH an index.html and an index.php.

Nginx prioritizes incorrectly prioritizes the index.html - deleting this resolved the issue.

Upvotes: 0

Jose Sandoval
Jose Sandoval

Reputation: 1

I realized that I was getting that error because the name of the app was the same as the name of an app that i had installed previously.

I solved this by simply changing the name of the app from. micro-app to micro-app2.

once micro-app2 was installed, then I tried to install micro-app again, and it work fine

Upvotes: 0

Aditya
Aditya

Reputation: 131

This happened with our sales channel too and the reason was that shopify's "APP_UNINSTALLED" webhook does not get called properly or some delay happens so the session_token does not get cleared (which you might be doing in that webhook handler). And because of using an expired token, you end up on that page.

How we fixed it was we retrieve the saved session from session storage and use it to hit any shopify admin api and if that fails with a 401 or 403 error then we assume that it is an expired token and clear it.

Something like this:

app.get("/", async (req, res) => {
  if (typeof req.query.shop !== "string") {
    res.status(500);
    return res.send("No shop provided");
  }

  const shop = Shopify.Utils.sanitizeShop(req.query.shop) || "";
  const sessions = await Shopify.Context.SESSION_STORAGE.findSessionsByShop(shop);

  const { AccessScope } = await import(
  `@shopify/shopify-api/dist/rest-resources/${Shopify.Context.API_VERSION}/index.js`
  );

  const scope = await AccessScope.all({
    session: sessions[0],
  }).catch(async (err) => {
    // We check for the error status code and clear our storage
    if (err.response?.code === 401 || err.response?.code === 403) {
      sessions.forEach((session) => redisClient.del(session.id));
      await AppInstallations.delete(shop);
    }
  });
  const appInstalled = await AppInstallations.includes(shop);

  if (!appInstalled) {
    return redirectToAuth(req, res, app);
  }

  if (Shopify.Context.IS_EMBEDDED_APP && req.query.embedded !== "1") {
    const embeddedUrl = Shopify.Utils.getEmbeddedAppUrl(req);

    return res.redirect(embeddedUrl + req.path);
  }

  return handle(req, res);
)};

const AppInstallations = {
  includes: async function (shopDomain: string) {
    if (Shopify.Context.SESSION_STORAGE.findSessionsByShop) {
      const shopSessions =
        await Shopify.Context.SESSION_STORAGE.findSessionsByShop(shopDomain);
      if (shopSessions.length > 0) {
        for (const session of shopSessions) {
          if (session.accessToken) return true;
        }
      }
    }
    return false;
  },

  delete: async function (shopDomain: string) {
    if (Shopify.Context.SESSION_STORAGE.findSessionsByShop) {
      const shopSessions =
        await Shopify.Context.SESSION_STORAGE.findSessionsByShop(shopDomain);
      if (shopSessions.length > 0) {
        if (Shopify.Context.SESSION_STORAGE.deleteSessions) {
          await Shopify.Context.SESSION_STORAGE.deleteSessions(
            shopSessions.map((session) => session.id)
          );
        }
      }
    }
  },
};

Upvotes: 0

aarkerio
aarkerio

Reputation: 2354

If you are using the ruby shopify gem and you are finding this message only on the reinstalling app cases, you need to set nil on the shop.shopify_token and the shop.shopify_domain fields after you receive the uninstall webhook.

On my case, I'm using the now deprecated field "shop.myshopify_domain" to save the domain when the user uninstall the app.

If the user reinstalls (even many months after), find the old SQL row and switch the rows. That way the user will find his previous data.

Upvotes: 0

Mudassir
Mudassir

Reputation: 408

But what if the scenario is this, you cannot create a webhook before installing app Check this one: https://github.com/osiset/laravel-shopify/issues/1071

Upvotes: 0

Raskul
Raskul

Reputation: 2199

Yes, as Paul Odeon said after the user uninstalled the app, you need to delete your old shop information from your database.

I just want to mention how to do that with Laravel.

doc

on this page, you can find app/uninstalled webhook.

when the user installed the app, on the first page you should create the webhook.

in Laravel it's like this:

    $shop = Auth::user();

    $p = $shop->api()->rest('GET', '/admin/api/2021-07/webhooks.json', []);
    $webhooks = $p['body']['container']['webhooks'];

    if(count($webhooks) === 0){
        $p = $shop->api()->rest('POST', '/admin/api/2021-07/webhooks.json', [
            "webhook" => [
                "topic" => "app/uninstalled",
                "address" => env('APP_URL') . "/api/uninstalled/" . $shop->id,
                "format" => "json"
            ]
        ]);
    }

api.php:

Route::post('/uninstalled/{user_id}', 'WebhookController@uninstallAppWebhook');

controller:

public function uninstallAppWebhook($userId){
        \DB::table('users')->delete($userId);
    }

Upvotes: 0

Maris
Maris

Reputation: 684

For those using Ruby on Rails shopify_app gem:

We actually found an issue there - which might help others, to.

In: ShopifyApp::RequireKnownShop#check_shop_known

.../gems/shopify_app-18.0.2/app/controllers/concerns/shopify_app/require_known_shop.rb:24

code screenshot

We found an issue that basically the gem was just checking if the shop in DB is found by the domain name, and if it was, then it assumed that all is ok. But the app didn't get installed. So we needed to check that it can actually connect to Shopify API with the existing token - and if we cannot, then need to redirect to /login?shop=... so that it gets properly installed. Probably shopify_app gem shouldn't check that the token is valid/needs to be re-generated - but it would be nice if it did check that.

Upvotes: 2

Paul Odeon
Paul Odeon

Reputation: 4524

@Mudasser has answered his own question. You need to delete the old Shop (from the first installation) from the database then try the install again and it will work.

If you've correctly added the app uninstalled webhook you wont have this problem.

Upvotes: 15

Related Questions