You are correct; methods 1) and 2) will give you the same result but keeping two things in mind:
A) You need to make sure your FX forwards and xccy basis swaps are priced under the same collateral assumption.
B) The difference between the two methods is more a question of semantics because FX forwards and xccy basis swaps are mutually dependent, so it really depends what market data you have to start with.
A) By collateralisation I mean the amount regularly exchanged between the two parties of the swap/contract, on top of any coupons or notional payments scheduled, as the value of the swap/contract fluctuates with the market. In order to take out any credit risk issues, broker feeds assume perfect collateralisation (=> daily, no minimum transfer amount), and so should you for your pure "first-order" rates pricing purposes. But the currency which will be actually posted matters too since it will determine which discount curve and factors will ultimately be used. Xccy swaps vs USD are usually collateralised with US Dollars, which means the cashflows are discounted at Fedfunds. By saying "risk-free rate" I assume this is what you are referring to; the OIS discount rate of the corresponding currency.
B) You can bootstrap your FX forwards from the xccy basis curve or you can bootstrap you xccy bases from FX forwards, assuming you also have all the other curves needed for both discounting and libor forwards. Usually you would go from the xccy basis to FX forwards since the latter usually has market data only for short-term maturities (<1 year). More details on the methodology can be found in this answer to a related question:
Assuming you are looking at EURUSD discounted at Fedfunds, in the end what you end up with is:
- Fedfunds discount factors: df(FF) -> those can be applied to any USD amount in the future to get its USD PV.
- FX forwards: fwd(EURUSD) -> those can be applied to any EUR amount in
the future to get its USD-equivalent amount in the future
- Basis discount factors: df(EURUSD) -> those can be applied to any EUR amount in the future to get its EUR PV discounted at Fedfunds.
df(EURUSD) = df(FF) x fwd(EURUSD) / spot(EURUSD)
So what I mean is that depending on how you combine these factors (associative property of multiplication...) you can either call them FX forwards, single-currency discount factors or basis discount factors but it really comes down to the same thing.
One caveat is if you use a different market feed, like the EONIA/FEDFUNDS basis curve, to get your basis discount factors, but whether or not you find the same result depends on the non-arbitrage property of your market data.