The drops are random, but they do have weights - some items are more likely than others. Some time ago, the weights for Pokestops and gyms were altered such that gyms would give out potions and revives (supplies for battling) around 10 times more often. And pokestops would have a greater focus on pokeballs (supplies for catching).
This Reddit post breaks down the drop rates based on player research, and there is a Silph Road article on the drop rates of gifts. Between these we can assemble an approximate drop rate chart for the three main sources of common items:
Category | Gifts | Gyms | PokeStops
Balls | 33.33% | 47.66% | 73.70%
Potions | 13.88% | 19.20% | 2.81%
Revives | 9.72% | 9.27% | 0.61%
Berries | 8.39% | 23.83% | 22.81%
Evolution | 0.06% | 0.05% | 0.07%
Stardust | 34.62% | [n/a] | [n/a]
(Rates based on player data, and is assumed to be roughly accurate)
So are the drops rigged against individual players based on what they have? There is no evidence to support this (nor any to refute it). But I would suggest that the discrepancies noted in the question could be better explained by differences in the way each player interacts with the game:
Would you say you are mostly spinning Pokestops, rather than gyms? Is your friend mostly spinning gyms? Your friend who finds himself short on Pokeballs, does he catch more Pokemon per location spun than you? How many Pokeballs are wasted per catch attempt (missed throw, Pokemon broke free, hit the Pokemon during an invulnerable animation)?
If you haven't already, one way to partially mitigate some dry spells in the random drops is to use the coins from holding gyms to buy bag upgrades - this lets you hold more items so you don't run out as quick.
Another trick is to manually throw out unneeded items. If you have a decent stockpile of max/hyper potions, the regular potions are just taking up space. How many evolution items do you really need to hold on to (I try not to hold onto more than 2 each)? they can start to build up and take up valuable room. Nanab Berries - practically useless for catching, but good for farming stardust/candies in friendly gyms, so feed a bunch of them to Pokemon to free up backpack space.
Find a community online to share friend codes with. You can only open 20 gifts per day, but the more friends you have, the more likely you get 20 gifts to open. I frequently have to purge items in my backpack just to have room for all the items I get daily in this way. More drops = more chances for the items you need.