Closed Nuranto closed 3 years ago
Internal ticket ID MAGETWO-49202
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;
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.
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.
Related to #3572
Experiencing the same problem on version 2.0.8. The session object disappeared sometimes. Need to disable the cache to make it work.
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
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
$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
Hi @KalaiarasanSeetharaman, from this how to get customer ID i.e. how to get which customer is logged in.
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.
@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.
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;
}
}
@tehXor Thanks for the tip on flagging the layout as cachable=false.
That worked like a charm for me!
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.
@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.
@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
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!
I noticed that having all types of cache except
Full page cache
getting data from session works normally. So I guess the problem is inFull 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.
@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?
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.
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.
@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.
@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
@LucScu great! Let's use different services as intended.
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 :)
Magento2 still has Zend framework 1 and
prototype.js
inside
ZF1 is in process of elimination and some reminants of prototype.js
only 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.
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*/
}
}
}
@kazimnoorani8704 this is still using ObjectManager
and NOT RECOMMENDED as well. Looks how customer session in injected in core classes.
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
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();
}
}
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.
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.
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.
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 :)
Event :
catalog_product_get_final_price
I need the current logged in customer id.
On Observer :
=>
But I'm logged in in front, this is confirmed when using
$this->_httpContext->getValue(\Magento\Customer\Model\Context::CONTEXT_AUTH)
:Is this a bug ? Or am I wrong somewhere ?
(Note : if I dump
$_SESSION
, customer_id isNULL
too :()