From the point of the physics simulation (Bullet library) collision is interaction of two objects, so the question whether A collides with B or B collides with A is not relevant, or actually, both happen.
Collisions are hard to handle from that global collision event, as it’s fired for every colliding pair of objects. It’s possible that the “node A” or “node B” might swap between simulation steps (especially if the collision is broken off and then starts again) so you can’t rely on which is which.
Typically a game might be running a car logic script or component in the same node as the car rigidbody/collisionshape, and each such car logic object would listen to its own node’s collision events only: the NodeCollision category of events. Those events are easier to use as they have an “other node” parameter. Like this:
SubscribeToEvent(GetNode(), E_NODECOLLISIONSTART, HANDLER(MyLogicObject, HandleNodeCollisionStart));
void MyLogicObject::HandleNodeCollisionStart(StringHash eventType, VariantMap& eventData)
{
using namespace NodeCollisionStart;
Node* collidedWith = eventData[P_OTHERNODE].GetPtr();
...
}