There are two approaches:
- If the code initiating the operation can't even start it, it's reasonable to throw an error. That would be synchronous. 
- In situations where the asynchronous process is already underway and you're doing this, or if you simply prefer that the function never throws and always returns a promise, use - Promise.reject:
 - return Promise.reject(new Error("Item missing"));
 
(You don't have to use an Error with Promise.reject, just like you dont' have to with throw, but it's best practice in both cases.)
Two other comments on getFollowers:
- In general, if you already have a promise to work with, e.g. from - this.db.collectionGroupin this case, don't use- new Promise. Just chain from that promise. See this question's answers for details.
 
- I see in your question that - getFollowershas a- .catchhandler. That's usually not appropriate if the function returns a promise. Just allow the error to propagate.
 
So if you want to do a synchronous error when you can't even initiate the operation:
getFollowers(uid, auth){
    if(!uid){
        throw new Error("Item missing");
    }
    return this.db.collectionGroup(`following`)
        // ....
    });
}
if you prefer to use a rejected promise instead:
getFollowers(uid, auth){
    return !uid
        ? Promise.reject(new Error("Item missing"))
        : this.db.collectionGroup(`following`)
            // ....
        });
}