We've thought about this issue, and there are a couple solutions, but none are trivial.
From my understanding, it is possible to purchase DAI with fiat, and not have any Ether in that account (though this is weird - the DAI is essentially locked in that account until it gets funded, so I'm not sure how those services work).
What you could do is, instead, have the user transfer the tokens to a pre-computed address, where a contract account / identity contract will be deployed counterfactually (using create2). You can then set that contract to give allowance to your recipient and sidestep the issue that way. It's also possible to use some of this initial balance to pay for the deployment of the contract account itself, so there's no risk from the recipient side. The main issue with this setup is the need for the DAI to be sent to an address specified by your dapp.
This is quite complex and there are some tricky details involved; we'll probably have a more in-depth guide and tools to support this advanced use case in the near future. Stay tuned!