magento / magento2

Prior to making any Submission(s), you must sign an Adobe Contributor License Agreement, available here at: https://opensource.adobe.com/cla.html. All Submissions you make to Adobe Inc. and its affiliates, assigns and subsidiaries (collectively “Adobe”) are subject to the terms of the Adobe Contributor License Agreement.
http://www.magento.com
Open Software License 3.0
11.54k stars 9.32k forks source link

Cannot get customer session data #3294

Closed Nuranto closed 3 years ago

Nuranto commented 8 years ago

Event : catalog_product_get_final_price

I need the current logged in customer id.

On Observer :

    public function __construct(\Magento\Customer\Model\Session $customerSession)
    {
        var_dump($customerSession->getData());
    }

=>

  &array(5) {
    ["customer_group_id"]=>
    string(1) "1"
    ["customer_id"]=>
    NULL
    ["default_tax_billing_address"]=>
    NULL
    ["default_tax_shipping_address"]=>
    NULL
    ["customer_tax_class_id"]=>
    NULL
  }

But I'm logged in in front, this is confirmed when using
$this->_httpContext->getValue(\Magento\Customer\Model\Context::CONTEXT_AUTH):

array(2) {
  ["customer_group"]=>
  string(1) "1"
  ["customer_logged_in"]=>
  bool(true)
}

Is this a bug ? Or am I wrong somewhere ?

(Note : if I dump $_SESSION, customer_id is NULL too :()

sevos1984 commented 8 years ago

Internal ticket ID MAGETWO-49202

quienti commented 8 years ago

I can confirm this bug, when I'm logged in fronted

When I use this :

$ObjectManager = \Magento\Framework\App\ObjectManager::getInstance();
$session =  $ObjectManager->get('Magento\Customer\Model\Session');
return $session->isLoggedIn();

My return is false...

But, when I used this, it's work fine :

$ObjectManager= \Magento\Framework\App\ObjectManager::getInstance();
$context = $ObjectManager->get('Magento\Framework\App\Http\Context');
$isLoggedIn = $context->getValue(\Magento\Customer\Model\Context::CONTEXT_AUTH);
return $isLoggedIn;
SergeiKutanov commented 8 years ago

Experiencing the same problem. When I disable cache bin/magento cache:disable I can get if a customer is loged in from the Session object.

deepanshu27193 commented 8 years ago

Experiencing the same problem on version 2.0.2. Any updates for this issue or it is solved in any latest version ? I tried $_SESSION but its not working for category and product pages.

sengaigibon commented 8 years ago

Related to #3572

zzpaul commented 8 years ago

Experiencing the same problem on version 2.0.8. The session object disappeared sometimes. Need to disable the cache to make it work.

saravananvelu commented 8 years ago

I have installed Magento 2.1.1 latest version still facing this issue which is not able to retrieve customer data from session in product view page, when cache is enabled

bartoszkubicki commented 8 years ago

Also bug in Magento 2.1. I noticed that having all types of cache except Full page cache getting data from session works normally. So I guess the problem is in Full page cache.

I think it's related issue: https://github.com/magento/magento2/issues/6392

KalaiarasanSeetharaman commented 8 years ago

$ObjectManager= \Magento\Framework\App\ObjectManager::getInstance(); $context = $ObjectManager->get('Magento\Framework\App\Http\Context'); $isLoggedIn = $context->getValue(\Magento\Customer\Model\Context::CONTEXT_AUTH); return $isLoggedIn;

This thing worked for checking customer is logged in or not when page cache is enable We need to page cache for showing count for compare product , wishlist , cart count initially when customer gets logged in

deepanshu27193 commented 8 years ago

Hi @KalaiarasanSeetharaman, from this how to get customer ID i.e. how to get which customer is logged in.

tehXor commented 8 years ago

First of all I also would consider this a bug as it is really annoying and therefore should be fixed / handled better imho.

However I doubt the Mage Devs see it as bug as they always declare the code parts were they use \Magento\Customer\Model\Session themselves as not cacheable. So it looks like \Magento\Customer\Model\Session is not intended to work with cache. I'm not sure if it is true for all problems with \Magento\Customer\Model\Session but I guess it is for a lot of them.

We came across this problem in a custom block and could "fix" it easily be also declaring it as not cacheable in its layout config XML. So instead of `

we needed

`
in our XML. Maybe some other problems can be solved in a similar way.

@deepanshu27193 You cannot do this in an easy way, CONTEXT_GROUP and CONTEXT_AUTH are the only attributes provided by \Magento\Customer\Model\Context directly. There may be another way but it would probably be a little bit more complicated.

deepanshu27193 commented 8 years ago

@tehXor what another way are you talking about , any suggestion ?

and yes regarding your cacheable suggestion, i have one point, i already implemented this to avoid error but i revert back to normal because after that we experience page speed issue.

saravananvelu commented 8 years ago

I have tried like this and got the customer session object when the cache is enabled.

<?php

namespace Test\Stack\Model\Test;

use Magento\Framework\ObjectManagerInterface;

/**
 * @var \Magento\Framework\ObjectManagerInterface
 */
protected $_object;

class Test{

     public function __construct(ObjectManagerInterface $interface)
     {
        $this->_object = $interface;
     }

     public function getCustomerSession(){
        $customerSession = $this->_object->create('Magento\Customer\Model\SessionFactory')->create();
        return $customerSession;     
     }
}
davidstillson commented 7 years ago

@tehXor Thanks for the tip on flagging the layout as cachable=false.

That worked like a charm for me!

pantaoran commented 7 years ago

To all the people here suggesting to mark a block as non-cacheable: keep in mind that one non-cacheable block in a layout will make the entire layout non-cacheable (talking about full page cache here).

The consequence is that the page in question will never be cached by the FPC, and if your non-cacheable block happens to be in a page header/footer that you use on all your pages, then full-page caching will be completely broken for your entire website. That is a big performance price to pay.

JstrzAtW2M commented 7 years ago

@pantaoran have you come up with a solution around this? I haven't been to get anything to work. I almost got using SessionFactory to work, but it kept sending back the same session values even after I called session->setdata with new values.

pantaoran commented 7 years ago

@jstrez77 I'm not sure what exactly you're trying to solve. What I described in my last comment is exactly what happened to me until I realized how much worse I made it. I'm now trying to fix it, and it seems that the solution is to load user-specific data through javascript instead of php, this way the server page can still be cached and the client will still see relevant info for their account.

First I though that would have to be AJAX, but actually Magento already loads a bunch of data that you can just access without further calls to the server. Look at the example at https://github.com/magento/magento2/blob/develop/app/code/Magento/Theme/view/frontend/templates/html/header.phtml

Also, what helped me a lot in understanding all this is: https://inviqa.com/blog/how-full-page-cache-works-magento-2

southerncomputer commented 7 years ago

See customerSessionFactory for fix above- it doesn't contain full customer data but the ID is there - you can. manually l load customer object after grabbing the ID!

orlangur commented 7 years ago

I noticed that having all types of cache except Full page cache getting data from session works normally. So I guess the problem is in Full page cache.

This is NOT a problem in full page cache. It is supposed to work this way saving all necessary data in HttpContext so that when you serving cached page there is even no need to start PHP session.

See http://devdocs.magento.com/guides/v2.2/extension-dev-guide/cache/page-caching/public-content.html#configure-page-variations for details.

@Nuranto, http://devdocs.magento.com/guides/v2.1/extension-dev-guide/cache/page-caching/private-content.html explains how to pass customer-specific data properly.

LucScu commented 7 years ago

@orlangur What have we to do to retrieve customer's email for logged user with FPC enabled? It is absurd that there is no easy way to do so. Have we to follow all these steps http://devdocs.magento.com/guides/v2.1/extension-dev-guide/cache/page-caching/private-content.html?

orlangur commented 7 years ago

What have we to do to retrieve customer's email for logged user with FPC enabled?

Please use Magento Stack Exchange for questions. You can do it similar to "Welcome, %USERNAME%!" block.

It is absurd that ...

Feel free to suggest a better implementation.

korostii commented 7 years ago

Feel free to suggest a better implementation.

The $_isScopePrivate approach was perfect from extension developer point of view, but I believe it's now considered deprecated and discouraged by the core developers (not sure about the motivation for this decision, might be exactly because of some issues with cache) - it's even mentioned in the docs.

IMHO developer shouldn't need to go through that amount of effort in order to work around the caches. I wonder if maybe a way to fix\improve that $_isScopePrivate feature somehow is the way to go.

The most awkward part is that when you take glance into the core, looking for a working example and all you see are these $_isScopePrivate and cacheable=false. Not sure if that changed in 2.2.

orlangur commented 7 years ago

@korostii passing pieces of HTML via AJAX in 2k17, really? :)

The $_isScopePrivate is flawed by design (one small mistake and your customer private data is cached for everyone). Too bad this M1-style FPC mechanism was not eliminated at all (just because it requires a lot of refactoring).

and cacheable=false. Not sure if that changed in 2.2.

Didn't check 2.2 yet as well. For the 2.0 GA there was a separate effort to make all product/category/CMS pages not using the obsolete FPC mechanism. Some pages, like My Account, do not really suffer from being not cacheable.

Main problem is that developers still think in terms of generating some HTML thus getting an unexpected system behavior. I do agree that CustomerData mechanism could be a bit easier to use, hiding all unneeded implementation details under the hood.

LucScu commented 7 years ago

@orlangur I try to find a way by myself and after find it i will reply here (for anyone have some hints) https://magento.stackexchange.com/questions/152010/how-to-get-customer-email-from-javascript?noredirect=1#comment266673_152010

orlangur commented 7 years ago

@LucScu great! Let's use different services as intended.

korostii commented 7 years ago

passing pieces of HTML via AJAX in 2k17, really? :)

Well, Magento2 still has Zend framework 1 and prototype.js inside. In 2017. What's your point? :D

Too bad this M1-style FPC mechanism was not eliminated at all (just because it requires a lot of refactoring).

Well how would you expect extension and integrator developers to care about it, if it's not even done for the core yet? Looks like double standards to me.

I really hope the blocks cache\tags\variations\local storage system becomes the center of Magento 2's frontend fireworks. But I just don't see right now how could the outside developers transition to it en masse while it's still such a work in progress. Maybe, some other day :)

orlangur commented 7 years ago

Magento2 still has Zend framework 1 and prototype.js inside

ZF1 is in process of elimination and some reminants of prototype.jsonly left in Admin UI, it would be eliminated if needed just like it was done for storefront (a good one for 'up for grabs', by the way, last time I grepped there were like ~80 occurrences of it in require section of components).

if it's not even done for the core yet?

It was done for crucial pages, sometimes regressions happened like review block on product page, some third-party developers may be unaware and accidentally make such pages uncacheable :( That's why such ajaxified FPC need to be completely eliminated for good.

kazimnoorani8704 commented 5 years ago

You can try by creating an object of objectManager and should not use objectManager directly.

Use something like,

class Example extends \Magento\Framework\View\Element\Template
{
    private $_objectManager;
    public function __construct(
        \Magento\Framework\ObjectManagerInterface $objectmanager
    ){
        $this->_objectManager = $objectmanager;
    }

    public function getExample()
    {
        $customerSession = $this->_objectManager->create("Magento\Customer\Model\Session");
        if ($customerSession->isLoggedIn()) {
            $customerData = $customerSession->getCustomer()->getData();
            /*Your logic*/
        }
    }
}
orlangur commented 5 years ago

@kazimnoorani8704 this is still using ObjectManager and NOT RECOMMENDED as well. Looks how customer session in injected in core classes.

alamzaib commented 5 years ago

How i got it

$objectManager = '\Magento\Framework\App\ObjectManager'::getInstance(); $context = $objectManager->get('Magento\Framework\App\Http\Context'); $isLoggedIn = $context->getValue(\Magento\Customer\Model\Context::CONTEXT_AUTH);

now $isLoggedIn will give us weather customer is logged in or not if($isLoggedIn){ // code }

and then $customerSession = $objectManager->get('\Magento\Customer\Model\Session'); var_dump($customerSession->getCustomer()->getData());

to get customer information

munkhulzii commented 4 years ago

For me the session factory made the difference.


use Magento\Customer\Model\SessionFactory;

 public function __construct(
        SessionFactory $sessionFactory
    ) {
        $customerSession = $sessionFactory->create();
        if ($customerSession->isLoggedIn()) {
             // it works now
             $customerSession->getCustomer()->getSomeCustomAttribute();
        }
    }
stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed after 14 days if no further activity occurs. Thank you for your contributions.

soniclouds commented 3 years ago

A little late to the party, but found what appears to be a good solution, at least for me. Instead of using Magento\Customer\Model\Session, try calling 'isLoggedIn()' on Magento\Customer\Block\Account\AuthorizationLink. I had header-related issues (on homepage specifically) and this change solved it for me.

trunglv commented 2 years ago

So somewhat reason, Customer Session is modified by other functions before. It will work well if we create a new instance. Create

print_r( \Magento\Framework\App\ObjectManager::getInstance()->create(\Magento\Customer\Model\Session::class)->getData());

It won't work if we get already an instance one. GET

print_r( \Magento\Framework\App\ObjectManager::getInstance()->get(\Magento\Customer\Model\Session::class)->getData());

And use an instance from Constructor as well. By default, Object Manager will use GET function to inject an instance.

So I think Magento should fix it. It takes resources when we create a new more one for a class.

erikffflabel commented 1 year ago

when cache is enabled and you have session->getCustomerId = null issue, you just need to add Factory pattern Magento/blabla/Customer/SessionFactory

private SessionFactory $customerSessionFactory;

construct(SessionFactory $customerSessionFactory) { $this-customerSessionFactory = $customerSessionFactory; }

public function someFunction() { $sessionModel = $this->customerSessionFactory->create(); return $sessionModel->getCustomer()->getId() }

that is very good solution for this issue :)