You do not need a Doubly LL over a Double ended LL. A double ended LL (has pointer to head and tail) suffices.
For FIFO, the main operations are enqueue and dequeue. In linked list terms, this is add_to_end and remove_from_front. Both of these are O(1) operations with a double ended linked list.
If you needed a data structure that could operate both as a queue and a stack, then you would need a doubly linked list to get O(1) operations. The main operation that would take O(n) without a doubly linked list is remove_from_end/pop. The reason for this is that you would have to find the node one previous from the last (node3 in example below), set it to the tail and then remove its pointer to the node that you are removing. With a doubly LL, it is as simple as tail.prev to find this node; however, with a double ended LL, you would have to do a O(n) traversal to find that node.
First 1 - 2 - 3 - 4 Last
def remove_from_end():
# get node4 and remove node4 from being the tail. O(1) time as you have a pointer to the tail in a double ended LL.
# set tail node3 and remove the .next from node3 to node4. If you don't have .prev on node4, then it would take O(n) to find node3