Walk through what your attempt does: [] is sent to [] (this is correct). With a list with at least two elements (x:y:xs), your function tests x, throws out x and y and keeps filtering if the test passes (definitely not what you want), and throws out x and stops if the test fails (this is correct). A list with a single element errors out, as will many other lists with an odd number of elements (this is both bad and a clue to the correct answer).
Let's walk through a correct implementation a step at a time. As you wrote, we want filterFirst to take a predicate on a and a list of a and return another list of a:
filterFirst :: (a -> Bool) -> [a] -> [a]
The predicate type a -> Bool can't be broken down, but [a] can: there can be empty lists [] and nonempty lists x:xs, and there should be a case for each:
filterFirst p [] = ...
filterFirst p (x:xs) = ...
In the "base case" [], there's nothing left to filter, so we want this to be [], which is what you've written. Since p isn't used here, you could replace p in this case with _:
filterFirst _ [] = []
but you don't have to.
What we want to do with x:xs depends on the value of p x. If p x holds, we want a list that starts with x. The tail of this list should be xs, but with the first failing element removed. If p x fails, we want to throw out x (the first failing element) and keep xs (the list after the first failing element). So:
filterFirst p (x:xs)
| p x = x:filterFirst p xs
| otherwise = xs
And that covers all the possibilities, so we're done!
EDIT per dfeuer's comment.